Speedtest / Xor test

Speedtest / Xor test

imring

Вступление

Здравствуйте читатели. В "speedtest" статьях мы рассматриваем реализацию одного алгоритма в разных языках программирования и их реализаций (компиляторы и интерпретаторы). Оцениваем будем по скорости и по нагрузке процессора. Будет 10 запусков и оценивать буду среднее арифметическое.

Скорость буду измерять с помощью утилиты time и смотреть будем на значение user (время CPU, которое занял пользователь).

Результат исполнения ./xor

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

Скриншот программы htop

Устройство для измерения

Измерять я буду на своем настольном компьютере с такими характеристиками:

Алгоритм

Имеется файл 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.

Report Page