Периодически появляются темы, в которых сторонники разных языков утверждают, что их языки быстрее/лучше. Захотелось это проверить. В паре тредов в качестве примера упоминались конкретные тесты. Их я и реализовал.
Общая идея теста
Тест проводится на каком-либо примере, позволяющем проверить производительность в той или иной области.
Реализация для каждого языка должна быть максимально простой. Если для данного языка нет простой реализации поставленной задачи - такой язык не подходит для решения этой задачи. Если простого решения задачи нет ни на одном языке - такая задача не подходит для теста.
Замер выполнялся десяток раз и для каждого языка выбиралось наилучшее время. Чем время меньше - тем лучше.
.
Числодробилки: длинная арифметика
Проверялась скорость операций с длинной арифметикой. Это важно в мат.вычислениях, требующих высокой точности. Реализация на примере вычисления факториала числа 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?) - предлагайте. :)





