Ваша версия на python довольно неэффективна, потому что вы проверяете членство в списке, а не набор или требование (т. Е. Время поиска O (n) вместо O (1)).
Попробуйтевместо этого используйте set
кортежей или set
строк.Кортежи будут лучшим выбором, так как два файла могут быть разделены на разные разделители, но я не думаю, что вы увидите особенно большую разницу в производительности.tuple('something'.split())
относительно быстро по сравнению с тестированием на членство в очень длинном списке.
Кроме того, нет необходимости звонить inp.readlines()
.Другими словами, вы можете просто сделать
look_up = set(tuple(line.split()) for line in inp)
И вы должны увидеть значительное ускорение без необходимости изменять какие-либо другие части вашего кода, кроме tuple(line[:3])
, а не [line[0], line[1], line[2]]
.
На самом деле, grep и bash довольно хороши для этого ... (не проверено, но оно должно работать.)
while read line
do
grep "$line" "file2.txt"
done < "file1.txt"
Чтобы увидеть, какой из них быстрее, мы можем сгенерировать некоторые тестовые данные (~ 4500 клавиш в file1.txt
и 1000000 строк в file2.txt
) и тестирование простой версии Python того же самого (грубо ... строки будут напечатаны в другом порядке, чем версия grep.).
with open('file1.txt', 'r') as keyfile:
lookup = set(tuple(line.split()) for line in keyfile)
with open('file2.txt', 'r') as datafile:
for line in datafile:
if tuple(line.split()[:3]) in lookup:
print line,
Версия Python оказывается в ~ 70 раз быстрее:
jofer@cornbread:~/so> time sh so_temp149.sh > a
real 1m47.617s
user 0m51.199s
sys 0m54.391s
против
jofer@cornbread:~/so> time python so_temp149.py > b
real 0m1.631s
user 0m1.558s
sys 0m0.071s
Конечно, два примера подходят к проблемев совсем разными способами.Мы действительно сравниваем два алгоритма, а не две реализации.Например, если у нас есть только несколько ключевых строк в file1
, решение bash / grep легко выигрывает.
(Есть ли в bash какой-то встроенный контейнер с поиском O (1) для членства?(Я думаю, что у bash 4 может быть хеш-таблица, но я ничего о ней не знаю ...) Было бы интересно попробовать реализовать алгоритм, аналогичный приведенному выше в Python, на примере python ...)