Я пытаюсь получить максимальную производительность для создания большого файла XML в Python 2/Django.
Окончательный файл XML составляет ~ 500 МБ. Первый использованный подход был с lxml, но это заняло более 3,5 часов. Я протестировал с помощью xml.sax (XMLGenerator) и занял примерно столько же времени, 3,5 часа.
Я пытаюсь найти самый быстрый способ с наименьшим потреблением памяти. Я искал несколько дней, чтобы найти лучшие решения, но безуспешно.
код lxml:
from lxml import etree
tree_var = etree.Element("tree_var", version='1.2')
DATE = etree.SubElement(DATETIME, "DATE")
DATE.text = datetime.date.today().strftime('%Y-%m-%d')
products = FromModel.objects.all().values_list('product_id')
for product in products:
if product.state == 'new':
ARTICLE = etree.SubElement(tree_var, "ARTICLE", mode=product.state)
Код генератора XML:
from xml.sax.saxutils import XMLGenerator
from xml.sax.xmlreader import AttributesNSImpl
with open("tmp/" + filename + ".xml", 'wb') as out:
g = XMLGenerator(out, encoding='utf-8')
g.startDocument()
def start_tag(name, attr={}, body=None, namespace=None):
attr_vals = {}
attr_keys = {}
for key, val in attr.iteritems():
key_tuple = (namespace, key)
attr_vals[key_tuple] = val
attr_keys[key_tuple] = key
attr2 = AttributesNSImpl(attr_vals, attr_keys)
g.startElementNS((namespace, name), name, attr2)
if body:
g.characters(body)
def end_tag(name, namespace=None):
g.endElementNS((namespace, name), name)
def tag(name, attr={}, body=None, namespace=None):
start_tag(name, attr, body, namespace)
end_tag(name, namespace)
g.endDocument()
я почти уверен, что xml.sax использует меньше памяти и увеличивает размер файла в реальном времени. С другой стороны, lxml создает файл только в конце цикла, используя огромный буфер.
Любые идеи для помощи?
Спасибо!
XMLGenerator
. Вы можете найти пример того, как его использовать здесь< /а>. - person Josh Voigts   schedule 13.03.201812.8. Performing Simple Parallel Programming
вCHAPTER 12 Concurrency
- person Reidel   schedule 13.03.2018import codecs from multiprocessing.dummy import Pool, cpu_count def do_work(products): <write to file> def parallel(result=None): pool = Pool(cpu_count()-1) # to prevent GIL with codecs.open(filename.xml", 'w+', "utf-8") as fp: <do stuff> pool.map(do_work, loop_object) pool.close() pool.join() parallel()
я думаю, что можно улучшить память, но я доволен временем, которое я сэкономил на создании XML. - person xampione   schedule 20.03.2018