Понадобилось мне как-то сделать из таблички в питоне html. Табличка объемная вопрос оптимизации важен.
А тут на хабре
статья забавная появилась. Там в комментах рекомендуют использовать ''.join(list) вместо str += str.
Решил последовать совету и переписал свою функцию. А теперь самое интересное: соединение юникодных строк происходит действительно раз в 10 быстрее, но вот для ansi-строк проигрывает. Хотелось бы узнать почему так?
Вот полный код теста:
from time import time
printHeader = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/></head>
<body><h1>%s</h1><table cellspacing="0" cellpadding="0">
"""
s1 = (u'Тест', u'Еще тест')*8
s1 = [i.encode('cp1251') for i in s1]
s2 = [s1]*500
def table2html1(src, s1, printHeader):
s = printHeader % 'dfgsdfgsdfg'
s += '<tr>'
for col in s1:
s += '<td>%s </td>'%col
s += '</tr>\n'
for row in src:
s += '<tr>'
for col in row:
s += '<td>%s </td>'%col
s += '</tr>\n'
s += "</table></body></html>"
return s
def table2html2(src, s1, printHeader):
mkRow = lambda row: ''.join(sum((('<td>', col, ' </td>') for col in row), ()))
mkDoc = lambda doc: ''.join(sum((('<tr>', mkRow(row), '</tr>\n') for row in doc), ()))
return ''.join((printHeader % 'dfgsdfgsdfg', mkDoc([s1]), mkDoc(src), '</table></body></html>'))
from cStringIO import StringIO
def table2html3(src, s1, printHeader):
s = StringIO()
s.write(printHeader % 'dfgsdfgsdfg')
def mkDoc(doc):
for row in doc:
s.write('<tr>')
for col in row:
s.write('<td>')
s.write(col)
s.write(' </td>')
s.write('</tr>\n')
mkDoc([s1])
mkDoc(src)
s.write("</table></body></html>")
return s.getvalue()
t = time()
result1 = table2html1(s2, s1, printHeader)
print time()-t
t = time()
result2 = table2html2(s2, s1, printHeader)
print time()-t
t = time()
result3 = table2html3(s2, s1, printHeader)
print time()-t
with open('join1.html', 'wb') as fd:
fd.write(result1)
with open('join2.html', 'wb') as fd:
fd.write(result2)
with open('join3.html', 'wb') as fd:
fd.write(result3)
Тут еще одна версия есть с использованием cStringIO — table2html3.
Результаты:
0.00999999046326
0.0150001049042
0.0190000534058
Если закоментировать вверху s1 = [i.encode('cp1251') for i in s1]:
0.648000001907
0.018000125885
Traceback (most recent call last): # cStringIO с юникодом не работает, нужно оставить StringIO, но он медленнее.
Или я что-то упустил?