Jako iteruje nad całym plikiem drzewo jest budowane i żadne elementy nie są zwalniane. Zaletą tego jest to, że elementy pamiętają, kim jest ich rodzic, i można tworzyć ścieżki XPath, które odwołują się do elementów przodków. Wadą jest to, że może zużywać dużo pamięci.
W celu zwolnienia pamięci, jak analizować, użyj Liza Daly na fast_iter
:
def fast_iter(context, func, *args, **kwargs):
"""
http://lxml.de/parsing.html#modifying-the-tree
Based on Liza Daly's fast_iter
http://www.ibm.com/developerworks/xml/library/x-hiperfparse/
See also http://effbot.org/zone/element-iterparse.htm
"""
for event, elem in context:
func(elem, *args, **kwargs)
# It's safe to call clear() here because no descendants will be
# accessed
elem.clear()
# Also eliminate now-empty references from the root node to elem
for ancestor in elem.xpath('ancestor-or-self::*'):
while ancestor.getprevious() is not None:
del ancestor.getparent()[0]
del context
które można następnie wykorzystać tak:
def process_element(elem):
print "why does this consume all my memory?"
context = lxml.etree.iterparse('really-big-file.xml', tag='schedule', events = ('end',))
fast_iter(context, process_element)
Gorąco polecam the article na którym powyższy fast_iter
jest oparty; powinno to być szczególnie interesujące, jeśli masz do czynienia z dużymi plikami XML.
Przedstawiona powyżej wersja fast_iter
jest nieznacznie zmodyfikowaną wersją tego pokazanego w artykule jako . Ten jest bardziej agresywny w usuwaniu poprzednich przodków, dzięki czemu oszczędza więcej pamięci. Here you'll find a script, który pokazuje różnicę .
Dzięki! Zarówno twoje rozwiązanie, jak i to, które właśnie dodałem, wydają mi się skuteczne, jestem ciekaw, który z was i innych ludzi jest lepszym rozwiązaniem. Czy masz jakieś myśli? –
Okazuje się, że twoje rozwiązanie działa, a rozwiązanie http://effbot.org/zone/element-iterparse.htm (jeszcze nie zjadło całej mojej pamięci) –
Dziękuję! To jest wersja, która naprawdę działa. Wersje od Liza Daly, effbot i lxml oficjalne dokumenty NIE oszczędzały mi dużo pamięci. – fjsj