может кто-нибудь объяснить, почему следующий тривиальный код (реализация алгоритма Евклида, чтобы найти самый общий общий знаменатель) примерно в 3 раза медленнее, чем эквивалентный код в Ruby?
содержимое iter_gcd.py:
from sys import argv,stderr
def gcd(m, n):
if n > m:
m, n = n, m
while n != 0:
rem = m % n
m = n
n = rem
return m
# in Python3 code there is xrange replaced with range function
def main(a1, a2):
comp = 0
for j in xrange(a1, 1, -1):
for i in xrange(1, a2):
comp += gcd(i,j)
print(comp)
if __name__ == '__main__':
if len(argv) != 3:
stderr.write('usage: {0:s} num1 num2\n'.format(argv[0]))
exit(1)
else:
main(int(argv[1]), int(argv[2]))
содержимое iter_gcd.rb:
def gcd(m, n)
while n != 0
rem = m % n
m = n
n = rem
end
return m
end
def main(a1, a2)
comp = 0
a1.downto 2 do
|j|
1.upto (a2 - 1) do
|i|
comp += gcd(i,j)
end
end
puts comp
end
if __FILE__ == $0
if ARGV.length != 2
$stderr.puts('usage: %s num1 num2' % $0)
exit(1)
else
main(ARGV[0].to_i, ARGV[1].to_i)
end
end
Измерения времени выполнения:
$ time python iter_gcd.py 4000 3000
61356305
real 0m22.890s
user 0m22.867s
sys 0m0.006s
$ python -V
Python 2.6.4
$ time python3 iter_gcd.py 4000 3000
61356305
real 0m18.634s
user 0m18.615s
sys 0m0.009s
$ python3 -V
Python 3.1.2
$ time ruby iter_gcd.rb 4000 3000
61356305
real 0m7.619s
user 0m7.616s
sys 0m0.003s
$ ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
Просто любопытно, почему я получил такие результаты. Я считал, что CPython будет быстрее в большинстве случаев, чем МРТ и даже новый Ruby 1.9 на YARV, но этот "microbenchmark" действительно меня удивил.
Btw, я знаю, что могу использовать специализированную библиотечную функцию, такую как fractions.gcd, но я бы хотел сравнить реализации таких базовых и тривиальных языковых конструкций.
Я что-то пропустил или это реализация следующего поколения Ruby настолько улучшилась в области чистой скорости?