Самый быстрый язык программирования: Scala, Java или может быть Python?
Понадобилось мне написать программку, пересчитывающую массив географических координат из одной системы в другую. Написал на Ruby в несколько строчек. Время выполнения — 16,5 сек. Чего так долго? Решил написать то же самое, но на разных языках, чтобы заценить производительность современных языков программирования. Результаты оказались неожиданными.

[TOC Самый быстрый ЯП]
Ruby
Ruby простой, удобный и… очень медленный. Вообще-то, это мой любимый язык программирования. Нравится лаконичностью и универсальностью. Хочешь web-приложение — ставь Ruby on Rails и ваяй. Нужен скрипт для системного администрирования — Ruby тоже очень хорош. Но в Руби всё настолько модное, динамическое и объектно-ориентированное, что язык, прямо скажем, очень нетороплив. И это справедливая плата за удобство. 16,5 сек.
JRuby
Обалденный проект! JRuby берет скрип на Ruby и компилирует в байт-код Java. А VM от Явы славится своей отполированностью и производительностью. Плюс огромный бонус — возможность прозрачно вызывать из Ruby код на Java из миллиона первосортных библиотек и наоборот. Но не будем отвлекаться. Взял я свою программу и натравил на нее компилятор JRuby. Время расчетов сократилось в 2 раза и составило 8,6 секунды. Получаем ускорение в 2 раза с нулевыми затратами.
Go
Go — моднейший и распиаренный язык от Google. Программа компилируется в бинарный код. Разработчики обещают высочайшую производительность. Проверяем. 3,7 сек. Отлично! Но ведь Си всё равно будет быстрее?!
C
В отличии от Go, тут нет сборщика мусора и раздутого рантайма. Только хардкор! Берем gcc, компилируем, запускаем и получаем первый сюрприз — 4 секунды. Что за дела? Можно предположить, что у Go лучше оптимизация. Тогда попробуем и из gcc выжать максимум. Используем опции -O3 и -march=native (тест на i7). Получаем 3,7. Ровно столько же, сколько выдает Go.
Java
JRuby опробовали и получили 8,6. А что получится, если весь код сразу написать на Java? Тут нас ждет вторая неожиданность — 3,1 сек. Быстрее, чем Go и Си. Как это объяснить я не знаю. Возможно, кто-нибудь в комментариях расскажет, как код в виртуальной машине может выполняться быстрее нативного кода? У меня есть всего одна гипотеза и даже мне она кажется сомнительной: а вдруг виртуальная машина настолько умная, что оптимизирует код во время выполнения и распараллеливает часть задач? В любом случае, Java — это сила!
Scala
Модный ЯП, претендующий на роль убивца Java. Тоже компилируется в бинарный код для виртуальной машины Java. Синтаксис Scala намного более приятный и — что самое главное — намного более лаконичный. А что со скоростью? Наверное, примерно как у JRuby? И тут третий сюрприз — 3,1 сек., то есть как и у Java. Но если не округлять, что у Java 3.104 сек, а у Scala 3,091. Ну вообще!
JavaScript
Рассмотрим JavaScript на примере NodeJS 4-й ветки. Получилось 3,5 сек. Go и C посрамлены. Как интерпретируемая программа может оказаться быстрее нативного кода? Возможно, всё дело в чудо-движке V8 от Google, который не устают нахваливать за скорость. Кстати, это именно он установлен во всех браузерах Chrome и Chromium.
PHP
Вот мы и добрались до самого яркого представителя быдланской пэхапэплеяды. Использовалась версия PHP 5.6, хотя уже есть PHP 7, которая, как заявляют некоторые, примерно в 2 раза быстрее. Но 7 еще мало распространена, а тогда как версия 5.6 вездесуща. В режиме CLI программа отработала за 16,5 сек. Ровно столько же, сколько и на чистом Ruby. Мы получили мощное доказательство того, что не случайно специалисты объединили эти три прекрасные языка — PHP, Python, Ruby — в быдланскую плеяду. Кстати, о Python…
Python
Для теста я использовал Python третьей ветки (3.5). Запускаем, ждем, ждем, ждем… и через 51,412 сек. программа заканчивает расчеты. В быдланской плеяде новый «чемпион». Конечно, я сразу же решил, что где-то пропустил важный нюанс оптимизации. Пришлось погрузиться в изучение этого языка и прочитать не один трактат по оптимизации. Затем я переписал программу, хотя переписывать было почти нечего: включается таймер, далее идет цикл с вычислениями по жестко заданной формуле, таймер выключается и печатаются результаты. 3 часа чтения документации и еще час на оптимизацию кода дали поистине потрясающий результат: время работы сократилось с 51,412 до 50,336 сек.
Perl
Зачем нужен этот старый пердун среди молодых и сильных атлетов? А затем, что время от времени встречаю утверждение, что Perl — это как PHP, только в 100 раз круче и быстрее, поэтому многие крутые проекты пишут на Перле. Может и вправду быстрее? Запускаем и… 18 секунд. На помойку.
Какой язык программирования выбрать?
Любой, который больше нравится. За исключением Python, конечно. Но если требуется выполнить узкую задачу — большое количество арифметических вычислений — и требуется скорость, то Java и Scala очень хороши. Кстати, теперь я понял, почему Hadoop написан на Java, а Spark на Scala.
Сводная таблица
| Название | Время выполнения (меньше — лучше) |
|---|---|
| Scala | 3,1 |
| Java | 3,1 |
| JavaScript | 3,5 |
| Go | 3,7 |
| C | 3,7 |
| JRuby | 8,6 |
| Ruby | 16,5 |
| PHP | 16,5 |
| Perl | 18,0 |
| Python | 50,3 |
Методика
Тестовые программы состояли из 3 частей:
- Загрузка данных из файла CSV.
- Вычисления.
- Вывод результатов.
Таймер включался только перед выполнением второй части и выключался перед третьей частью. Считать время импорта данных из CSV не было смысла, так как для этого использовались достаточно объемные библиотеки, которые для каждого языка разные. Таймер включался только для блока вычислений, который во всех языках был одним и тем же. В конце работы программы печаталось два числа: контрольная сумма и время исполнения в миллисекундах. Принудительная оптимизация включалась только для gcc, в остальных случаях использовались параметры компиляции по умолчанию.
Краткость — сестра таланта
В качестве бонуса. Самый большой объем был у программы на Java. Самый малый — у Perl. Почти столько же у JavaScript.