Speedtest / Xor test
imringВступление
Здравствуйте читатели. В "speedtest" статьях мы рассматриваем реализацию одного алгоритма в разных языках программирования и их реализаций (компиляторы и интерпретаторы). Оцениваем будем по скорости и по нагрузке процессора. Будет 10 запусков и оценивать буду среднее арифметическое.
Скорость буду измерять с помощью утилиты time и смотреть будем на значение user (время CPU, которое занял пользователь).

Нагрузку буду изменять с помощью программы htop, которая выводит информацию о процессах и о потребности в системных ресурсах, а так же позволяет остановить или удалить процесс.

Устройство для измерения
Измерять я буду на своем настольном компьютере с такими характеристиками:
- Intel Pentium G4620 3.70GHz
- DDR4 8GB/2666 Team T-Force Vulcan Z Red
- Crucial DDR4-2133 8192MB PC4-17000
- Windows 10 2004 + WSl 2 (Ubuntu 20.04)
Алгоритм
Имеется файл gta3.img (940 064 768 байтов). Читаем данный файл "чанками", размером 2048 байтов, и над каждым байтом производим xor 0xFF и записываем данный "чанк" в другой файл, например, в gta3.img-xor.
Исходные коды программ можете найти в этом репозитории*: https://github.com/FishLakeDev/speedtest/tree/main/xor
Результаты каждого теста можете скачать отсюда: https://t.me/fishlakedev_files/3
Благодарю тех, кто написал мне код на некоторых языках программирования. Спасибо.
*В коде языка C для вывода ошибки я использовал printf, потом на следующий день перезаписал на fprintf(stderr).
C
Данный код написал r4nx.
gcc
Использовал компилятор gcc 9.3.0 без оптимизации.

Во время записи в файл ЦП нагружается до 100%, потом падает до 5%.

Средний результат: real: 15.367s, user: 2.192s, sys: 1.421s.
gcc -O2
Тот же gcc, только с включённой оптимизацией.

Вначале ЦП нагружается до 70%, потом так же падает до 2-5%.

Благодаря оптимизации, результаты user стали лучше в 4 раза.
Средний результат: real: 13.736s, user: 0.539s, sys: 1.030s.
clang
Версия: 10.0.0.

Нагрузка аналогична с gcc.

Средний результат: real: 15.474s, user: 1.730s, sys: 1.159s.
clang -O2
Тот же clang, только с оптимизацией 2 уровня.

Нагрузка так же аналогична с gcc -O2.

А вот результаты, по сравнению с gcc -O2, стали лучше.
Средний результат: real: 12.276s, user: 0.206s, sys: 1.034s.
C++
g++
Использовал компилятор g++ 9.3.0 без оптимизации.

C++ немного дольше обрабатывали, чем C, нагрузка аналогична.

Средний результат: real: 17.428s, user: 2.634s, sys: 1.624s.
g++ -O2
Всё тоже самое, только с включенной оптимизацией.

Аналогично с gcc -O2 - максимальная нагрузка ЦП 70%.

Средний результат: real: 14.290s, user: 0.739s, sys: 1.252s.
clang++
Версия: 10.0.0.

Тоже самое, как и в g++.

Средний результат: real: 16.479s, user: 2.819s, sys: 1.389s.
clang++ -O2

Нагрузка аналогична с g++ -O2.

Средний результат: real: 15.387s, user: 0.672s, sys: 1.215s.
Golang
Данный код написал RinatNamazov.
Использовал go версии 1.15.6.

Программа запустила 5 потоков и из-за чего быстро справилась с файлом. Нагрузка ЦП ~80%.

Средний результат: real: 14.674s, user: 1.082s, sys: 1.867s.
Rust
Данный код написал RinatNamazov.
Версия: 1.49.0.

При записи в файл, нагрузка на ЦП был 100%, потом опустился до 2-5%.

Средний результат: real: 33.276s, user: 19.621s, sys: 1.618s.
opt-level=2
Теперь попробую запустить с оптимизацией 2 уровня.

Нагрузка не превышала 80%, а после записи была на уровне 2%.

Результаты улучшились в 80 раз!
Средний результат: real: 13.799s, user: 0.239s, sys: 1.421s.
Lua
Использовал Lua 5.3.3.

Нагрузка ЦП всегда 100%.

Средний результат: real: 150.224s, user: 147.201s, sys: 2.343s.
JIT
Раз уж у Lua так плохо выходит, то решил ускорить с помощью LuaJIT. Версия: 2.1.0-beta3.

Как и с Lua - нагрузка всегда 100%.

Результаты стали намного лучше, чем с "чистым" Lua.
Средний результат: real: 33.054s, user: 23.202s, sys: 1.586s.
PHP
JIT off
Данный код написал RoffDaniel.
Версия интерпретатора: 8.0.0.

Нагрузка ЦП: 100%.

Средний результат: real: 57.878s, user: 54.091s, sys: 1.543s.
JIT on
Всё тот же PHP, только с включённым JIT (-d opcache.enable_cli=1 -d opcache.jit_buffer_size=128M).

Нагрузка никак не поменялась с выключенным JIT.

Зато справилась быстрее на +-15 сек.
Средний результат: real: 43.662s, user: 36.029s, sys: 1.924s.
Python
Данный код написал r4nx.
Версия: 3.8.5.

Нагрузка ЦП: 100%.

Средний результат: real: 82.643s, user: 79.572s, sys: 1.508s.
PyPy
Теперь попробуем ускорить Python с помощью реализации PyPy (JIT). Версия: 7.3.1.

Нагрузка в общем-то не поменялась.

Результаты очень сильно удивили меня, примерно в 10 раз улучшились.
Средний результат: real: 18.829s, user: 7.132s, sys: 1.263s.
Node.js
Данный код написал molimawka.
Версия: 10.19.0

Node запустила около 10 потоков и нагрузка на 3 ядрах ~20%, а один достигает 100%.

Средний результат: real: 42.209s, user: 21.041s, sys: 53.529s.
Итоги

C clang -O2 и Rust opt-level=2 справились лучше всех, хуже всех - Lua. Менее нагруженные оказались C/C++ -O2, Rust opt-level=2 и Golang. Любителем системных ресурсов оказался Node.js.
Скоро буду проводить другие тесты и, возможно, пополнять кол-во языков программирования.
Спасибо, что прочитали данную статью и подписывайтесь на мой канал в Telegram.