LINUX.ORG.RU
ФорумTalks

Небольшой бенчмарк Rust vs C++

 , , ,


0

7

Я тут вам покушать принёс.

Rust: https://github.com/KivApple/rust_benchmark

C++: https://github.com/KivApple/cxx_benchmark

Реализован алгоритм построения icosphere. Этот алгоритм запускается 10000 раз и замеряется среднее время исполнения. Алгоритм реализован практически дословно на обоих языках. Для небольшой математики используется glm для C++ и glam для Rust. Также алгоритм использует стандартные контейнеры HashMap и Vec для Rust и std::unordered_map и std::vector для C++.

Результаты (указаны в порядке запуска тестов, каждый тест был запущен два раза, чтобы немного нивелировать влияние изменений частоты и температуры процессора, всякий кешей и т. п):

Rust: 211 us
MSVC: 606 us
GCC: 497 us
Clang: 575 us
Rust: 211 us
MSVC: 598 us
GCC: 496 us
Clang: 587 us

Тестовое железо: Core i7-1165G7, 64 GB RAM, Windows 11 (мне быстрее всего было это запустить на Windows машине, плюс так получилась возможность забенчить ещё и MSVC для полноты картины, так же надо учесть, что в программе нет ни I/O, ни многопоточности, так что едва ли ОС будет влиять на производительность, а если и будет, то опять же оба языка в равных условиях).

Все проекты собраны в Release режиме (cargo build --release, cmake -DCMAKE_BUILD_TYPE=Release) под 64 бита.

Критика бенчмарка принимается (я понимаю, что это один частный use-case, но в рамках него можете указать на какие-то неточности замеров или несоответствия алгоритмов для разных языков). Также можете попробовать запустить на своих машинах со своими компиляторами (код достаточно тривиальный для понимания).

UPD: Версии компиляторов:

> rustc --version
rustc 1.64.0 (a55dd71d5 2022-09-19)
> clang --version
clang version 15.0.2
Target: x86_64-pc-windows-msvc
Thread model: posix
> cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.32.31329 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.
> gcc --version
gcc (GCC) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
★★★★★

Последнее исправление: KivApple (всего исправлений: 2)
Ответ на: комментарий от rumgot

js - не легко читать, сколько я не видел кода на js - всё это был дичайший говнокод. JS не позволяет писать читаемый код.

Java - возможно, хотя мне Java не нравится идиосинкратически.

emorozov
()
Последнее исправление: emorozov (всего исправлений: 2)
Ответ на: комментарий от firkax

С++ не заточен ни под что конкретное, он позволяет как использовать абстракции, так и писать свои велосипеды, просто средств для их написания больше.

а мы заранее знаем всю «геометрию» использования памяти, можно статически считать индекс в статической памяти

Это максимум сведётся к тому, что мы можем найти какую-то хорошую хеш-функцию, задача-то по-прежнему состоит в том, чтобы быстро искать некоторое значение по ключу из двух uint32.

А ещё разместить их так чтоб процовый кеш лучше работал.

Многие реализации хешмапы с этим и так хорошо справляются.

f1u77y ★★★★
()
Ответ на: комментарий от mxfm

Ну хешмапа в расте действительно работает быстрее, чем в С++, это обсуждалось уже много раз (точнее, не совсем это, а то что хешмапа в С++ медленная).

f1u77y ★★★★
()
Ответ на: комментарий от grem

Может он опции оптимизации для C++ не включал.

Кстати да, вполне возможно. У меня gentoo, и все собирается с флагами из make.conf:

COMMON_FLAGS="-O2 -pipe -march=znver3"

т.е. с этими флагами в том числе собрана стандартная библиотека C++. Правда не уверен, что это так уж сильно влияет на производительность.

selim
()
Ответ на: комментарий от selim

Оптимизации на производительность влияют очень сильно.

Всякие STL на то и STL что собираются каждый раз наново. Во всяком случае unordered_map или что там ТС юзал…

Ваш К.О.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

За счёт того что в в C++ мапа с нодами и на бакетах, а в Rust– без нод, и при этом на открытой адресации, что лучше как в плане количества абстрактных операций, так и в плане cache-friendly.

f1u77y ★★★★
()
Ответ на: комментарий от f1u77y

С++ не заточен ни под что конкретное, он позволяет как использовать абстракции, так и писать свои велосипеды, просто средств для их написания больше.

Хорошо, может и так, я затрудняюсь тогда сформулировать идею но тем не менее не отказываюсь от неё.

Это максимум сведётся к тому, что мы можем найти какую-то хорошую хеш-функцию,

«Хорошую» это ту что без коллизий и соответственно можно выкинуть всю обработку хеш-таблицы и заменить плоским массивом с индексами, и оптимизировать уже его а не общий случай.

firkax ★★★★★
()
Ответ на: комментарий от firkax

ту что без коллизий

В этой задаче лично мне как-то неочевидно, какими такими свойствами обладает множество ключей, что для него можно сделать perfect hash. Обычно в алгоритмах, где он используется, все операции вставки предшествуют операциям поиска, а тут такого свойства явно не наблюдается.

соответственно можно выкинуть всю обработку хеш-таблицы и заменить плоским массивом с индексами

Хешмапа с открытой адресацией – это и есть обычный массив, просто с обработкой коллизий. В случае отсутствия коллизий это вообще буквально одно и то же.

f1u77y ★★★★
()
Ответ на: комментарий от firkax

Хорошо, может и так, я затрудняюсь тогда сформулировать идею

В моём понимании эта идея состоит в том, что в си мало языковых конструкций для создания zero-overhead абстраций, и из-за этого часто приходится писать велосипеды «под нужную задачу».

f1u77y ★★★★
()
Ответ на: комментарий от emorozov

js - не легко читать, сколько я не видел кода на js - всё это был дичайший говнокод. JS не позволяет писать читаемый код.

Херово совсем у тебя с формальной логикой.

crutch_master ★★★★★
()
Ответ на: комментарий от mxfm

Верный признак секты

Увы и ах. Программирование скатывается в религию.

crutch_master ★★★★★
()
Ответ на: комментарий от emorozov

JS вполне позволяет писать читаемый код, но сектанты и экстремисты от вредительства типа фейсбука с этим активно борются внедряя антипаттерны в качестве стандарта разработки, т.е. если у вас есть например React, TypeScript и их линтерные правила не писать трудночитаемый код просто не получится

Syncro ★★★★★
()
Последнее исправление: Syncro (всего исправлений: 1)
Ответ на: комментарий от f1u77y

А ну вот ты подсказал. Только не так. В Си наличие оверхеда у любых абстракций (в том числе и якобы zero) настолько бросается в глаза, что их сразу выкидывают и заменяют на неабстрактные безоверхедные реализации.

firkax ★★★★★
()
Ответ на: комментарий от question4

Как различаются объёмы скомпилированных бинарников?

Если собирать, как в стартовом сообщении, то у меня получилось 32 720 (cpp) vs 9 194 616 (rs). (и 142 vs 137 соответственно)

Если собрать со static

g++ -O3 -static main.cpp -o cxx_benchmark_s
то 2 354 736

Тогда и по скорости получается практически одинаково.

Ryzen 4650G

Toxo2 ★★★★
()
Последнее исправление: Toxo2 (всего исправлений: 1)
Ответ на: комментарий от question4

А вообще раст умеет делать рантайм отдельной библиотекой?

да, но пока нет.

Да умеет, но она разная для каждой версии.

То есть если сейчас сделать, то бинарник будет требовать библиотеку 1.64 и не запустится на компьютере с 1.63 и перестанет запускаться после обновления компилятора и рантайма до 1.65.

Поэтому статическая линковка и по-умолчанию.

https://www.reddit.com/r/rust/comments/us328s/comment/i91219n/?utm_source=share&utm_medium=web2x&context=0

fsb4000 ★★★★★
()
Ответ на: комментарий от firkax

наличие оверхеда у любых абстракций (в том числе и якобы zero)

Довольно громкое утверждение, интересно послушать аргументы в его пользу. Желательно, чтобы в них не фигурировали компиляторы 20-летней давности.

f1u77y ★★★★
()
Ответ на: комментарий от f1u77y

Оверхед от абстракций не только тот, который лишний код в обработчике абстракции, но и тот, что ты под неё код, её использующий, тоже пишешь по-другому. Ну хорошо, где-то и такого нет, но много где есть.

firkax ★★★★★
()

какова цель бенча ? что изначально хотелось сравнивать и зачем ??

потому что сравнивались хеш-таблицы и аллокаторы объектов. Отдельно хеши скорее ноздря-в-ноздрю, а аллокаторы в Rust быстрее (ровно до известной поры :-) )

MKuznetsov ★★★★★
()
Ответ на: комментарий от question4

Из этих 9мб это 90% дебаг инфа чтобы бэктрейсы красивые печатать и тп. Если сделать strip то вангую станет не больше чем 1mb бинарь.

pftBest ★★★★
()
Ответ на: комментарий от ox55ff

Опять же ядро линукса пропатчено, чтобы неиспользуемую память возвращать обратно в винду.

Это ж обычный ballooning. Он в лялексе 1000 лет как есть даже в KVM.

hateyoufeel ★★★★★
()
Ответ на: комментарий от firkax

Вместо std::map<std::string, T> делают hashMap[strlen(key)] = (void*)123;

MOPKOBKA ★★★★★
()

В расте медленный дефолтный хэшер, в доке написано зачем, если интересно.

% ./target/release/rust_benchmark
Mesh generation time: 153 us
% ./target/release/rust_benchmark
Mesh generation time: 153 us
% ./target/release/rust_benchmark
Mesh generation time: 154 us

Добавляем одну зависимость, меняем одну строчку и получаем…

% ./target/release/rust_benchmark
Mesh generation time: 52 us
% ./target/release/rust_benchmark
Mesh generation time: 54 us
% ./target/release/rust_benchmark
Mesh generation time: 54 us

Но это уже неспортивно (:

% ./cxx_benchmark
Mesh generation time: 151 us
% ./cxx_benchmark
Mesh generation time: 150 us
% ./cxx_benchmark
Mesh generation time: 151 us

А разницы то почти и нет на моём Ryzen 4700U.

anonymous-angler ★☆
()
Ответ на: комментарий от anonymous-angler

А какой хешер подключил? Я читал, что дефолтный имеет защиту (через рандомизацию хешей) от DoS специально подобранными ключами для создания коллизий. У меня же все ключи генерируются самой программой и, как следствие, доверенные, и мне не нужна защита от DoS.

KivApple ★★★★★
() автор топика

AMD Ryzen 7 5700G

for i in {1..10}; do ./target/release/rust_benchmark; done
Mesh generation time: 110 us
Mesh generation time: 112 us
Mesh generation time: 110 us
Mesh generation time: 114 us
Mesh generation time: 112 us
Mesh generation time: 113 us
Mesh generation time: 110 us
Mesh generation time: 112 us
Mesh generation time: 111 us
Mesh generation time: 110 us
for i in {1..10}; do ./cxx_benchmark; done
Mesh generation time: 146 us
Mesh generation time: 125 us
Mesh generation time: 126 us
Mesh generation time: 123 us
Mesh generation time: 122 us
Mesh generation time: 124 us
Mesh generation time: 120 us
Mesh generation time: 120 us
Mesh generation time: 125 us
Mesh generation time: 120 us
zezic ★★★★
()

UPDATE

Добавил ещё один бенчмарк - парсинг шрифта в формате PF2:

Windows:

[Rust]
Mesh generation time: 60 us
Font loading time: 1521 us
[MSVC]
Mesh generation time: 406 us
Font loading time: 1899 us
[GCC]
Mesh generation time: 383 us
Font loading time: 1740 us
[Clang]
Mesh generation time: 380 us
Font loading time: 1717 us

WSL:

[Rust]
Mesh generation time: 47 us
Font loading time: 687 us
[GCC]
Mesh generation time: 134 us
Font loading time: 663 us
KivApple ★★★★★
() автор топика
Ответ на: комментарий от AntonI

За счёт того, что это убогая перепаста C++-хешмапы. Почему они тащат всё это себе? Ну просто для того, чтобы врать.

Допустим, до того как они перепастили цпп-хешмапы - у них было днище, которое они сделали сами. Оно сливало вообще всему. И пришлось срочно костылять и придумывать легенду про маня-атаки. Конечно же, всё это днище не тормозило из-за хеша, но зато адепты везде бегали и врали.

right_security
()

Ты бы хотя бы в бенчмарк свой добавил тесты на корректность результата.

right_security
()
Ответ на: комментарий от KivApple

Там, кстати, два GCC - один это собственно MinGW, другой - cygwin. У бинарей собранным вторым будет в зависимостях cygwin1.dll, или как-то так. ЕМНИП, у первого лучше со скоростью, но хуже с POSIX, у второго ровно наоборот.

hatred ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.