LINUX.ORG.RU

Правильно ли я пишу на Rust?

 , ,


1

7

Часто мелькает Rust и в новостях, и в темах. Решил попробовать переписать один тест с С на Rust. Для сравнения написал вариант и на C++. На Rust получилось в 4+ раза медленнее, чем на С и в 2+ раза медленнее, чем на C++. Есть подозрение, что я делаю что-то неправильно, но не знаю что. Помогите, пожалуйста, разобраться.

UPD. Мои цифры:

$ gcc c_v1.c -Ofast -march=native
$ ./a.out 3000
16.439091
-287.250083
$ g++ cpp_v2.cpp -Ofast -march=native
$ ./a.out 3000
31.3826
-287.25
$ rustc rust_v1.rs -C opt-level=3 -C target-cpu=native
$ ./rust_v1 3000
71.570172703s
-287.2500833333321
★★★

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

Ну и сравнивать нужно без fast-math, ибо это фича компилятора, а не языка.

Лолшто? Ну давай не будем использовать O3 тоже этож тоже фича компилятора…

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

Лолшто? Ну давай не будем использовать O3 тоже этож тоже фича компилятора…

Да уж, растишники поражают своей непосредственностью и наивностью.

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

Напомни, где там у Rust стандарт на nightly фичи.

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

Нету смысла цепляться за fast_math. Он тут полностью до лампочки.

Мы уже определили что at() с ювелирной точностью замедляет C++ до скорости Rust.

Вопрос остается, почему unsafe+get_unchecked+get_unchecked_mut обратно не ускоряет Rust до скорости С++ с квадрантыми скобками.

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

А то ieee формат не вносит. Всё равно если важна точность нужно менять алгоритм вычислений и приводить на каждом шаге округление к нужной точности.

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

Так-с, код на C++ уже замедлили, осталось «всего лишь» ускорить код на Rust.

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

Ну там функциональный код, он может тоже не делать проверки кстати, так как там функции заранее известно что она движется по валидным индексам. А ФП оптимизатор вытрет. Так что мне кажется это из той же оперы, но что-то заставило оптимизатор таки сработать лучше с функциональным кодом чем get_unchecked

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

Не, ну я про нарушения стандарта ieee не знал, но обоснование насчёт точности канает только в двух случаях, и ни один из них не подходит под этот конкретный код.

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

Тогда остаётся gcc vs llvm.

Я тут давеча Skia тестировал. Так вот версия собранная gcc в три раза медленнее. И это на одной кодовой базе. А мы про разные языки говорим...

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

Завтра ТС забудет написать f*_fast и опять будет рассказывать про «медленный» Rust.

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

gcc vs llvm

Какой-то туповатый аргумент. Rust же на LLVM, и он медленнее.

А сишный вариант собирается gcc, и почему-то «медленным» gcc он получает двойное преимущество перед языками для школьников вроде Rust.

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

Да, действительно. Сейчас под рукой другая машина, потому цифры будут другие:

$ clang -Ofast -march=native c_v1.c -o c
$ ./c 3000
17.679873
-287.250083
$ clang++ -Ofast -march=native cpp_v1.cpp -o cpp
$ ./cpp 3000
55.875
-287.25
$ rustc rust_v1.rs -C opt-level=3 -C target-cpu=native
$ ./rust_v1 3000
17.34767689s
-287.2500833333321

В целом код понятен (не смотря на то, что я совсем не знаю Rust). За исключением этой строки:

*c_val = a_row.iter().zip(t_row.iter()).fold(0.0, |sum, (&a,&t)| unsafe{ fadd_fast(fmul_fast(a,t), sum) } );

Видимо, тут есть лямбда, но кроме неё незнакомые для меня zip, fold итд. Наверное, они относятся к приёмам функционального программирования, об этом есть в книге о Rust? Или лучше сначала где-то в другом месте почитать об этом и потом браться за книгу о Rust?

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

Про итераторы и замыкания немного есть тут: https://doc.rust-lang.org/book/ch13-00-functional-features.html

Что почитать по функциональным штукам (zip, map, fold и т.п.) не подскажу. Применительно к Расту, всё что они делают неплохо описано в https://doc.rust-lang.org/core/iter/trait.Iterator.html

zip объединяет пару итераторов в один, который выдаёт пары значений.

iter.fold(init, f) - это, в общем, цикл по итератору. Делает то же самое, что и

let mut state = init;
for v in iter {
    state = f(state, v);
};
return state;
red75prim ★★★
()
Ответ на: комментарий от anonymous

Но для получения костылей нужно сначала выстрелить себе в ногу.

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