Вот скрипт, который анализирует один миллион <instrumentConfiguration/>
элементов (967MB
файл) за 40
секунды (на моем компьютере) без использования большого объема памяти.
Пропускная способность 24MB/s
.cElementTree page (2005)
сообщает 47MB/s
.
#!/usr/bin/env python
from itertools import imap, islice, izip
from operator import itemgetter
from xml.etree import cElementTree as etree
def parsexml(filename):
it = imap(itemgetter(1),
iter(etree.iterparse(filename, events=('start',))))
root = next(it) # get root element
for elem in it:
if elem.tag == '{http://psi.hupo.org/ms/mzml}instrumentConfiguration':
values = [('Id', elem.get('id')),
('Parameter1', next(it).get('name'))] # cvParam
componentList_count = int(next(it).get('count'))
for parent, child in islice(izip(it, it), componentList_count):
key = parent.tag.partition('}')[2]
value = child.get('name')
assert child.tag.endswith('cvParam')
values.append((key, value))
yield values
root.clear() # preserve memory
def print_values(it):
for line in (': '.join(val) for conf in it for val in conf):
print(line)
print_values(parsexml(filename))
Вывод
$ /usr/bin/time python parse_mxml.py
Id: QTOF
Parameter1: Q-Tof ultima
source: nanoelectrospray
analyzer: quadrupole
analyzer: time-of-flight
detector: microchannel plate detector
38.51user 1.16system 0:40.09elapsed 98%CPU (0avgtext+0avgdata 23360maxresident)k
1984784inputs+0outputs (2major+1634minor)pagefaults 0swaps
Примечание: Код хрупок предполагает, чтопервые два потомка <instrumentConfiguration/>
- это <cvParam/>
и <componentList/>
, и все значения доступны в виде имен или атрибутов тегов.
При производительности
ElementTree 1.3 примерно в 6 раз медленнее, чем cElementTree 1.0.6 в этом случае.
Если вы замените root.clear()
на elem.clear()
, тогда код будет на ~ 10% быстрее, но в ~ 10 раз больше памяти.lxml.etree
работает с вариантом elem.clear()
, производительность такая же, как и для cElementTree
, но он потребляет в 20 (root.clear()
) / 2 (elem.clear()
) раз больше памяти (500 МБ).