работает или нет? Может кто глянуть?
https://gist.github.com/n-bes/d6a3eb12c49c4c928452556df4bcff33
https://youtu.be/g-WPhYREFjk?t=3416
На годболт выведи
Там с рандомом плохо
Суть в том чтобы посмотреть asm а для этого и одной функции хватит.
https://rust.godbolt.org/z/xeP483Mzh
Судя по всему, работает. Только ты неправильно godbolt используешь, туда имеет смысл класть на проверку минимальные куски кода, обозримые, и проверять на хотя бы втором уровне оптимизации (ключ -C opt-level=2). Я проверил на двух вариантах: pub fn sum(conditions: &[bool], values: &[u32]) -> u32 { let mut sum = Wrapping(0); for i in 0..3 { if conditions[i] { sum += Wrapping(values[i]); } } sum.0 } и pub fn sum(conditions: &[bool], values: &[u32]) -> u32 { let mut sum = Wrapping(0); for i in 0..3 { sum += Wrapping((conditions[i] as u32) * values[i]); } sum.0 } Судя по ассемблеру, во втором коде команд перехода существенно меньше, чем во втором.
11,001 ns/iter К слову операции которыя длятся пару тактов смысла бенчить мало - любая фоновая задача в операционке и результаты плывут
Это число не так считается, конечно
начало топика читал?
sorry, ты первый и ответил)
Да. И если бы ты действительно хотел избавиться от лишних бранчей, то написал как-то так: let values = &values[..500]; let conditions = &conditions[..500]; for i in 0..500 { ...
Я как-то ожидал, что компилятор по-умнее, и в рамках маленькой функции сможет собрать наиболее оптимизированный код
Не-а. Сообщение о выходе за границы включает в себя ошибочный индекс, поэтому снизить количество проверок до одной компилятор не может, ибо это поменяет наблюдаемое поведение. А вот если сразу заранее отрезать слайс нужного размера, то компилятор уже может доказать, что индекс всегда находится в нужных пределах, выкинуть проверки и векторизовать код
Обсуждают сегодня