Я нахожу, что простые вещи, такие как вызовы функций и циклы, и даже просто циклы, увеличивающие счетчик, занимают far больше времени в Python и Ruby, чем в Chicken Scheme, Racket или SBCL.
Почему это так? Я часто слышу, как люди говорят, что медленность - это цена, которую вы платите за динамические языки, но Lisps очень динамичны и не смехотворно медленны (они обычно меньше, чем в 5 раз медленнее C, Ruby и Python могут входить в двойные цифры). Кроме того, стиль Lisp использует рекурсию, а не всегда хвостовую рекурсию, много, стек - это связанный список продолжений в куче и т.д., Которые, похоже, являются вещами, которые должны сделать Lisp медленнее, чем Python в стиле императивного стиля и Ruby.
Racket и SBCL JITted, но Chicken Scheme либо статически компилируется, либо использует не оптимизирующий интерпретатор, оба из которых должны быть плохо подходят для динамических языков и медленны. Тем не менее, даже используя наивный интерпретатор csi
для Chicken Scheme (который даже не делает компиляцию байт-кода!), Я получаю скорости далеко за пределами Python и Ruby.
Почему именно Python и Ruby настолько смехотворно медленны по сравнению с аналогично динамическими Lisps? Это потому, что они объектно ориентированы и нужны огромные vtables и типы heirarchies?
Пример: факториальная функция. Python:
def factorial(n):
if n == 0:
return 1
else:
return n*factorial(n-1)
for x in xrange(10000000):
i = factorial(10)
Ракетка:
#lang racket
(define (factorial n)
(cond
[(zero? n) 1]
[else (* n (factorial (sub1 n)))]))
(define q 0)
(for ([i 10000000])
(set! q (factorial 10)))
Результаты синхронизации:
[email protected] /scratch> time racket factorial.rkt
racket factorial.rkt 1.00s user 0.03s system 99% cpu 1.032 total
[email protected] /scratch> time python factorial.py
python factorial.py 13.66s user 0.01s system 100% cpu 13.653 total