Vladimir
уже нашел код
Маjко
https://gist.github.com/mersinvald/2c4cc8e5838e783f1b8c7ef2056543fd
Сережа
хотя это уже не та функция будет, и функциональщина ваша тоже возвращает вектор векторов
Маjко
Маjко
Я ж его на локалхосте писал
Vladimir
fn imper(x: u8, y: u8) -> Vec<Vec<bool>> { let mut result = Vec::new(); for _ in 0..y { let mut row = Vec::new(); for _ in 0..x { row.push(true) } result.push(row) } result } fn iter(x: u8, y: u8) -> Vec<Vec<bool>> { (0..y) .map(|_| (0..x) .map(|_| true) .collect()) .collect() } fn main() { let mut x = imper(5, 5); x[0][1] = true; let mut y = iter(5, 5); println!("{:?} {:?}", x, y); }
Vladimir
нашел исходный
Vladimir
)
Маjко
Но никто так и не смог объяснить почему итеративная так тормозит
Маjко
Ассемблерщики, вперед
Vladimir
ну всмысле
Vladimir
там же аллокация каждый Row
Маjко
А с итераторами нет?
Vladimir
А итераторы с наименованными функциями могут оптимизироваться
Vladimir
больше простора
Маjко
Давай по русски
Маjко
В чем простор тут?
Маjко
Что итераторы делают иначе здесь?
Маjко
Точно такой же вектор векторов
Vladimir
на тебе третий код fn macrovec(x: u8, y: u8) -> Vec<Vec<bool>> { vec![vec![false; x as usize];y as usize] }
Anonymous
ну мб он видит что лямбда игнорирует аргументы
Vladimir
кто быстрее?)
Маjко
Ща
Vladimir
лямбды
Маjко
И что?
Vladimir
ну и значит он может его свернуть в что-то более простое
Vladimir
типа того макроса
Vladimir
test imper_bench ... bench: 1,799 ns/iter (+/- 225) test iter_bench ... bench: 1,079 ns/iter (+/- 328) test iter_macro ... bench: 1,041 ns/iter (+/- 137)
Маjко
Дак и циклы выше игнорируют
Маjко
Не аргумент вообще)
Anonymous
о циклах выше сложнее судить
Vladimir
угу
Маjко
Почему?
Vladimir
сложно развернуть .push в memset
Vladimir
(не в аллокациях дело)
Vladimir
хотя может и в них, но если например заменить внутренние на let mut row = Vec::with_capacity(x as usize); row.resize(x as usize, false); result.push(row)
Vladimir
он лучше понимает что ему делать
Vladimir
оптимизатор
Маjко
Vladimir
ну видимо условие не может выкинуть и оно его и губит
Маjко
Зачем лишний ресайз?
Cuno
Ассемблерщики, вперед
Чот там ассемблерный листинг почти на 600 строк
Vladimir
смысле лишний
Vladimir
он не лишний
Маjко
Чем он не лишний?
Vladimir
let mut result = Vec::with_capacity(y as usize); for _ in 0..y { let mut row = Vec::with_capacity(x as usize); row.resize(x as usize, false); result.push(row) } result
Vladimir
он заменяет внутренний цикл
Маjко
Зачем тут resize?
Маjко
Ах бож
Маjко
Понятно
Маjко
Я протупил
Маjко
Забенчи
Vladimir
test imper_bench ... bench: 1,124 ns/iter (+/- 337) test iter_bench ... bench: 1,090 ns/iter (+/- 254) test macro_bench ... bench: 1,048 ns/iter (+/- 149)
Vladimir
до ресайза test imper_bench ... bench: 1,757 ns/iter (+/- 394)
Маjко
Окей, уже очень близко
Vladimir
ну там погрешность больше чем разница
Vladimir
так что смириться можно
Маjко
Маjко
У меня нет
Маjко
Маjко
Причем я вообще циклы у себя убрал
Маjко
А вообще лучше не ебать мозги и сделать ленивый итератор :)
Маjко
Но это уже другая история
Маjко
Я имею в виду возвращать итератор
Маjко
А не вектор
պլհկ
Н А Й Т Л И
Vladimir
если убрать внешний вектор
Vladimir
то скорость одинаковая
Vladimir
у всего
Сережа
С И С Т Е М Н О Е П Р О Г Р А М И Р О В А Н И Е
Vladimir
значит проблема именно в том, что компилятор не справляется с вложенными циклами
Маjко
Ну короч оптимайзер во внутреннем цикле путается
Маjко
Всем итераторы посоны
Маjко
Юзаем итераторы
Маjко
Циклы медленные
Сережа
в котором ты не можешь сказать как это работает, ну там кароч это оптимизируется, хрен знает
Маjко
А тебе не насрать, покуда ПОСЛЕ ПРОФИЛИРОВАНИЯ тебе не надо оптимизировать?