Почему Python замедляется при разборе XML-файла dblp? - PullRequest
0 голосов
/ 13 мая 2019

Я пытаюсь извлечь некоторые данные из довольно большого XML-файла (записи dblp для тех, кто знаком с ним). Для этой цели я использую слегка измененную версию быстрого парсера, который я нашел на github, который работает так:


def fast_iter(context, func,*args, **kwargs):
    collaborations = [Top level elements I need]
    #Bunch of local variables

    #read chunk line by line
    for event, elem in context:

        if elem.tag in collaborations and event == "start":
            #Print to console that we are entering a top level element I might need
            tag = elem.tag
            print(elem.tag,event)

        #Additional processing only on the tags I need

        if elem.tag == tag and event == 'end':
            #Reset local variables
            #Print to console that the element is done
            print(elem.tag,event)

        #Regardless of the outcome of the processing
        #Free the memory from the last used element
        if event=="end":
            elem.clear()
            while elem.getprevious() is not None:
                del elem.getparent()[0]
    del context
    #clear chunks

#@func: process_element
#@param elem : parsed data of chunk
#@param fout : file name to write
#@desc: It is handler to write content. just write content to file
def process_element(elem, fout):
    #Write to file if I hit a top level element
    #That I actually needed
    print("writing ... " + elem)
    print(elem, file=fout)

if __name__ == "__main__":
    fout = open('parsed_data.txt', 'w')
    context = etree.iterparse('dblp.xml', load_dtd=True,html=True, events=["start", "end"])
    fast_iter(context, process_element, fout)

Как я уже говорил, это большой XML-файл (2,3 ГБ, если я правильно помню), поэтому я ожидаю, что выполнение займет некоторое время; Тем не менее, я заметил, что после того, как скрипт начинает работать, выполнение становится все медленнее и медленнее (на что указывает скорость, с которой я получаю начальные распечатки на консоль), даже если функция не загружает память, поскольку она освобождает ее. на каждом цикле.

Что мне здесь не хватает? Это ожидаемое поведение, потому что я печатаю так много материала для утешения? В таком случае, как я могу иметь какое-либо указание на то, что скрипт обрабатывает файл, не замедляя фактическое выполнение?

В качестве дополнительного примечания хочу отметить, что дерево, построенное из файла XML, является совершенно уникальным; как утверждают авторы:

" Как правило, наш XML представляет собой небольшой, но очень длинный список записей XML. Корневой элемент содержит несколько миллионов дочерних элементов, но обычно ни один элемент не является более глубоким, чем третий уровень. "

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

...