python файловая операция замедляется на массивных текстовых файлах - PullRequest
0 голосов
/ 14 июля 2020

Этот python код замедляется, чем дольше он работает.

Кто-нибудь, пожалуйста, скажите мне, почему?

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

от 10к до 20к уходит 2 сек c. от 300к до 310к занимает примерно 5 мин. и становится хуже. Код работает только в части ELSE до этого момента, и 'listoflines' является постоянным в этой точке (850000 строк в списке), а тип 'list []', а также 'offset' - это просто константа 'int' в в этой точке.

Исходный файл содержит от миллионов строк до более чем 20 миллионов строк.

'фиктивная строка не в listoflines' должна выполняться каждый раз в одно и то же время.

with open(filename, "rt") as source:
    for dummyline in source:
        if (len(dummyline) > 1) and (dummyline not in listoflines):
            # RUN compute
            # this part is not reached where I have the problem
        else:
            if dummyalreadycheckedcounter % 10000 == 0:
            print ("%d/%d: %s already checked or not valid " % (dummyalreadycheckedcounter, offset, dummyline) )
            dummyalreadycheckedcounter = dummyalreadycheckedcounter +1

Ответы [ 2 ]

1 голос
/ 14 июля 2020

То же мнение с @Sedy Vlk. Вместо этого используйте ha sh (это словарь в python).

clines_count = {l: 0 for l in clines}
for line in nlines:
    if len(line) > 1 and line in clines_count:
        pass
    else:
        if counter % 10000 == 0:
            print ("%d: %s already checked or not valid " % (counter, line) )
        counter += 1
1 голос
/ 14 июля 2020

на самом деле в операция для списка не одна и та же каждый раз, на самом деле это O (n), поэтому она становится все медленнее и медленнее по мере добавления

, которое вы хотите использовать, см. Здесь https://wiki.python.org/moin/TimeComplexity

Вы не просили об этом, но я бы предложил превратить это в конвейерную линию обработки, чтобы ваша вычислительная часть не смешивалась с логикой дедупликации c

def dedupped_stream(filename):
    seen = set()
    with open(filename, "rt") as source:
        for each_line in source:
            if len(line)>1 and each_line not in seen:
                seen.add(each_line)
                yield each_line

тогда вы можете сделать только

for line in dedupped_stream(...):
    ...

вам не нужно будет беспокоиться о дедупликации здесь вообще

...