Я написал быстрый Python-скрипт для сравнения двух файлов, каждый из которых содержит неупорядоченные хэши, чтобы убедиться, что оба файла идентичны, кроме порядка. Затем я переписал его на Ruby для образовательных целей.
Реализация Python занимает несколько секунд, а реализация Ruby - около 4 минут.
У меня такое ощущение, что это, скорее всего, из-за недостатка знаний Ruby, какие-либо идеи о том, что я делаю неправильно?
Среда - Windows XP x64, Python 2.6, Ruby 1.8.6
Python
f = open('c:\\file1.txt', 'r')
hashes = dict()
for line in f.readlines():
if not line in hashes:
hashes[line] = 1
else:
hashes[line] += 1
print "Done file 1"
f.close()
f = open('c:\\file2.txt', 'r')
for line in f.readlines():
if not line in hashes:
print "Hash not found!"
else:
hashes[line] -= 1
f.close()
print "Done file 2"
num_errors = 0
for key in hashes.keys():
if hashes[key] != 0:
print "Uneven hash count: %s" % key
num_errors += 1
print "Total of %d mismatches found" % num_errors
рубин
file = File.open("c:\\file1.txt", "r")
hashes = {}
file.each_line { |line|
if hashes.has_key?(line)
hashes[line] += 1
else
hashes[line] = 1
end
}
file.close()
puts "Done file 1"
file = File.open("c:\\file2.txt", "r")
file.each_line { |line|
if hashes.has_key?(line)
hashes[line] -= 1
else
puts "Hash not found!"
end
}
file.close()
puts "Done file 2"
num_errors = 0
hashes.each_key{ |key|
if hashes[key] != 0
num_errors += 1
end
}
puts "Total of #{num_errors} mismatches found"
РЕДАКТИРОВАТЬ Чтобы получить представление о масштабе, каждый файл имеет довольно большой размер, более 900 000 хешей.
ПРОГРЕСС
Используя рекомендации nathanvda, вот оптимизированный скрипт ruby:
f1 = "c:\\file1.txt"
f2 = "c:\\file2.txt"
hashes = Hash.new(0)
File.open(f1, "r") do |f|
while line = f.gets
hashes[line] += 1
end
end
not_founds = 0
File.open(f2, "r") do |f|
while line = f.gets
if hashes.has_key?(line)
hashes[line] -= 1
else
not_founds += 1
end
end
end
num_errors = hashes.values.to_a.select { |z| z != 0}.size
puts "Total of #{not_founds} lines not found in file2"
puts "Total of #{num_errors} mismatches found"
В Windows с Ruby 1.8.7 оригинальная версия занимала 250 секунд, а оптимизированная версия - 223.
На виртуальной машине Linux! работает под управлением ruby 1.9.1, оригинальная версия работала за 81 секунду, примерно в 1/3 времени, как windows 1.8.7. Интересно, что оптимизированная версия заняла больше времени на 89 секунд. Обратите внимание, что хотя строка = ... была необходима из-за ограничений памяти.
В Windows с Ruby 1.9.1 оригинал занял 457 секунд, а оптимизированная версия - 543.
В Windows с jRuby оригинал занял 45 секунд, а оптимизированная версия - 43.
Я несколько удивлен результатами, я ожидал, что 1.9.1 будет улучшением по сравнению с 1.8.7.