Периодически появляются темы, в которых сторонники разных языков утверждают, что их языки быстрее/лучше. Захотелось это проверить. В паре тредов в качестве примера упоминались конкретные тесты. Их я и реализовал.
Общая идея теста
Тест проводится на каком-либо примере, позволяющем проверить производительность в той или иной области.
Реализация для каждого языка должна быть максимально простой. Если для данного языка нет простой реализации поставленной задачи - такой язык не подходит для решения этой задачи. Если простого решения задачи нет ни на одном языке - такая задача не подходит для теста.
Замер выполнялся десяток раз и для каждого языка выбиралось наилучшее время. Чем время меньше - тем лучше.
.
Числодробилки: длинная арифметика
Проверялась скорость операций с длинной арифметикой. Это важно в мат.вычислениях, требующих высокой точности. Реализация на примере вычисления факториала числа 30000.
$ make
Language real user system
c++ 0.179 0.175 0.004
php 0.307 0.292 0.015
perl (gmp) 2.045 2.041 0.004
ocaml 2.109 1.840 0.269
ocaml (recurse) 5.015 4.743 0.271
java 8.422 8.571 0.176
ruby 8.974 8.963 0.007
python 17.609 17.602 0.004
bc 49.716 49.607 0.099
perl 123.891 123.840 0.014
Замечание: Хотя нерекурсивная версия для ocaml-а написана «не совсем» в функциональном стиле, она работает в два с половиной раза быстрее, чем рекурсивная. Почему?
.
Объекты: создание и удаление
Проверялась скорость создания и удаления объектов. Это важно в ООП-задачах при передаче объектов, как параметров. Реализация теста подсказана форумом (последнее время недоступен)
$ make
Language real user system
c++ (stack) 0.614 0.613 0.000 <1 MB
c++ (heap) 11.489 11.484 0.002 <1 MB
c++ (pool) 1.929 1.909 0.001 <1 MB
java 2.703 2.511 0.185 170 MB
ocaml 100.633 100.301 0.152 1 MB
python 389.973 389.882 0.009 3 MB
php 535.231 535.064 0.011 7 MB
ruby 756.593 680.874 75.535 3 MB
perl 4549.582 4548.612 0.027 3 MB
Замечание1: Можно было бы оставить только один тест для С++, но любители Java могли бы возмутиться, что C++ выделяет объект в стеке, а Java - в heap-е, и это нечестно по отношению к Java (и к тому же не возможно при большой глубине рекурсии и больших объектах). Потому добавлен С++ heap-тест (т.к. в Java для таких объектов автоматическое управление памятью, пришлось использовать его аналог - auto_ptr в С++).
Но тут сторонники С++ могли возмутиться, что С++-ный аллокатор оптимизирован для выделения больших объектов, и работает неэффективно для частого мелкого выделения. Поэтому был добавлен тест с более подходящим аллокатором (boost::object_pool).
Замечание2: Поскольку тест работал с памятью, логично было замерять, сколько же памяти в нем используется. И из всех тестируемых языков java - единственный, потребовавший 170МБ. Остальные уложились в десяток.
.
Выводы (если очень хочется): ООП-задачи кроме как на С++ и Java эффективно решать больше не на чем (но если важна память - остается только С++). А задачи, требующие высокой точности вычислений, быстрее всего решаются на С++. Его догоняют языки, умеющие работать с сишной libgmp, хотя и они примерно на порядок отстают от С++ по скорости.
Воспроизвести результаты можно скачав архив с тестами, и выполнив make в bash-е (для замера использовался bash-евый time, чтобы заменить его на что-то свое - надо править Makefile).
Все коды GPLv3+, можно их модифицировать, дополнять своими языками и выкладывать, куда угодно. Если есть еще примеры задач, на которых можно было бы провести тест, реализации тестов на других языках, или способы улучшения имеющихся (как ускорить perl?) - предлагайте. :)