Отображение прогресса синтаксического анализатора Python при загрузке огромного файла - PullRequest
2 голосов
/ 16 июня 2009

Я использую встроенный в Python парсер XML для загрузки 1,5-гигабайтного XML-файла, и это занимает целый день.

from xml.dom import minidom
xmldoc = minidom.parse('events.xml')

Мне нужно знать, как проникнуть внутрь этого и измерить его прогресс, чтобы я мог показать индикатор выполнения. есть идеи?

У minidom есть другой метод parseString (), который возвращает дерево DOM, предполагая, что передаваемая вами строка является допустимым XML. Если бы я сам разбил файл на куски и передал их в parseString по одному, мог бы я объединить все DOM-деревья вместе в конце?

Ответы [ 4 ]

5 голосов
/ 16 июня 2009

вы используете case требует, чтобы вы использовали sax-парсер вместо dom, dom загружает все в память, sax вместо этого будет выполнять построчный анализ, и вы будете писать обработчики для событий по мере необходимости это может быть эффективным, и вы сможете написать индикатор прогресса также

Я также рекомендую попробовать парсер expat, иногда это очень полезно http://docs.python.org/library/pyexpat.html

для прогресса, используя саксофон:

когда саксофон читает файл постепенно, вы можете обернуть файл, который вы передаете, своим собственным и отслеживать, сколько было прочитано.

редактирование: Мне также не нравится идея разделить файл самостоятельно и присоединиться к DOM в конце, так что вы лучше пишете свой собственный xml-парсер, я рекомендую вместо этого использовать sax-парсер Мне также интересно, какова ваша цель чтения файла 1,5 гига в дереве DOM? похоже, саксофону было бы лучше здесь

5 голосов
/ 16 июня 2009

Рассматривали ли вы использовать другие средства парсинга XML? Построение дерева таких больших XML-файлов всегда будет медленным и занимать много памяти. Если вам не нужно все дерево в памяти, анализ на основе потока будет намного быстрее. Это может быть немного сложным, если вы привыкли к манипулированию XML на основе дерева, но это окупится в виде огромного увеличения скорости (минуты вместо часов).

http://docs.python.org/library/xml.sax.html

3 голосов
/ 16 июня 2009

У меня есть кое-что очень похожее для PyGTK, а не PyQt, использующего API pulldom. Он вызывается чуть-чуть за раз с использованием событий простоя Gtk (чтобы графический интерфейс не блокировался) и генераторов Python (чтобы сохранить состояние анализа).

def idle_handler (fn):
  fh = open (fn)  # file handle
  doc = xml.dom.pulldom.parse (fh)
  fsize = os.stat (fn)[stat.ST_SIZE]
  position = 0

  for event, node in doc:
    if position != fh.tell ():
      position = fh.tell ()
      # update status: position * 100 / fsize

    if event == ....

    yield True   # idle handler stays until False is returned

 yield False

def main:
  add_idle_handler (idle_handler, filename)
2 голосов
/ 16 июня 2009

Слияние дерева в конце было бы довольно легко. Вы можете просто создать новый DOM и добавить к нему отдельные деревья по одному. Это дало бы вам достаточно точно настроенный контроль над ходом синтаксического анализа. Вы можете даже распараллелить его, если хотите, создавая разные процессы для анализа каждого раздела. Вам просто нужно убедиться, что вы разбили его разумно (не разбивая по середине тега и т.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...