Rust круче C++? Часть 1: скорость

morett1m 48 минут назад Краткое содержание статьи Rust круче C++? Часть 1: скорость Средний 16 мин 1.2K Блог компании Beget Rust * C++ * Программирование * Высоконагруженные системы * Обзор Привет, Хабр!Спор «Rust или...
Will Anthropic have the best AI model at the end of October 2026?
Значимый прорыв формирует отрасль ИИ: morett1m 48 минут назад Краткое содержание статьи Rust круче C++? Часть 1: скорость Средний 16 мин 1. 2K Блог компании Beget Rust * C++ * Программирование * Высоконагруженные системы * Обзор Привет, Хабр!
Спор «Rust или C++» идёт с 2015 года, с выхода Rust 1. 0, и за одиннадцать лет превратился в отдельный жанр со своими приколами. «В Rust на каждом индексе проверка, вот он и тормозит».
Технические детали
«В плюсах проверок нет, значит, быстрее». «Ага, а у Rust ссылки не пересекаются, так что быстрее как раз он». «Паника дорогая», «исключения дорогие», «абстракции бесплатные».
Каждая сторона уверена в своём, а в ассемблер почти никто не смотрит, хотя ответ лежит прямо там (и местами он неприятный для обеих сторон). В одну статью вопрос «круче ли Rust, чем C++» не влез, так что это первая часть, и она про скорость. Безопасность и прочие поводы поругаться ждут своей очереди.
Две ссылки, которые точно не пересекаютсяПервым идёт аргумент про ссылки, и тут сразу важный нюансик. Rust и clang оба отдают код в LLVM, хоть и разных версий, так что главные разницы в ассемблере я дальше проверяю с двух сторон: если она пропадает, когда меняешь одну подсказку компилятору, значит, дело было в подсказке. g++ позовём третьим, у него свой оптимизатор и свои привычки.
Отраслевые последствия
Начнём с крошечного примера, на нём всё видно сразу:pub fn add_twice(a: &mut i32, b: &i32) { *a += *b; *a += *b; }На C++ то же самое пишется через int& и const int&, тело один в один. А ассемблер разный:; Rust add_twice: mov eax, dword ptr add eax, eax add dword ptr , eax ret ; clang -O3 (у g++ то же самое, только операнды в другом порядке) add_twice: mov eax, dword ptr add eax, dword ptr mov dword ptr , eax add eax, dword ptr mov dword ptr , eax retRust прочитал b один раз, удвоил и прибавил к a. C++ записал a и снова полез за b в память, и по-другому он не может: a и b вполне могут смотреть на одно и то же число, вызов add_twice(x, x) в C++ законный и обязан учетверить x.
В Rust такой вызов даже не соберётся, на add_twice(&mut x, &x) компилятор ответит error: cannot borrow x as immutable because it is also borrowed as mutable. Раз пересечься ссылки не могут, rustc честно сообщает об этом LLVM атрибутом noalias. То есть мы получаем такое обещание, пока функция работает, эту память либо вообще никто не меняет, либо меняют только через эту ссылку.
В промежуточном представлении его видно прямо в объявлении функции:define void @add_twice(ptr noalias ... %b)Почему общая ссылка & на тип с UnsafeCell внутри этот noalias не получает (у &mut он остаётся) и к чему это приводит, мы подробно разбирали в статье про UnsafeCell и noalias, так что здесь пропущу. Самое забавно, что фокус всё это работает в обе стороны.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.



