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ко
Ща
Ма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ко
Зачем лишний ресайз?
Маjко
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ко
Но это уже другая история
Alex
Маjко
Я имею в виду возвращать итератор
Маjко
А не вектор
պլհկ
Н А Й Т Л И
Vladimir
если убрать внешний вектор
Vladimir
то скорость одинаковая
Vladimir
у всего
Сережа
С И С Т Е М Н О Е П Р О Г Р А М И Р О В А Н И Е
Vladimir
значит проблема именно в том, что компилятор не справляется с вложенными циклами
Маjко
Ну короч оптимайзер во внутреннем цикле путается
Маjко
Всем итераторы посоны
Маjко
Юзаем итераторы
Маjко
Циклы медленные
Сережа
в котором ты не можешь сказать как это работает, ну там кароч это оптимизируется, хрен знает
Маjко
А тебе не насрать, покуда ПОСЛЕ ПРОФИЛИРОВАНИЯ тебе не надо оптимизировать?