Ayrat
понял тебя сейчас
Ayrat
да, понятно почему я раньше такого не видел. я не пиховал мутабельные биндинги в матч с туплем
Ayrat
достаточно узкий кейс
Ayrat
и внезапные аллокаци
gsomix
Одно плохо, что мы это во флудилке обсуждаем. :)
Nikolay
Кстати, в Fabulous’e это оптимизировано таким образом, и там скорее всего писал Сайм, значит он в курсе 🤔
Igor
Если убрать mutable, то компилятор сможет оптимизировать match.
это же легко сделать, кстати станет еще чуть быстрее
gsomix
это же легко сделать, кстати станет еще чуть быстрее
Я думал о рекурсивной версии. В том же виде, как compareWith сделан в стандартной библиотеке.
Nikolay
@omgszer seq builder vs seq.filter
Ayrat
а вот это удивительно
Nikolay
let compareFilter (a: IComparable seq) (b: IComparable seq) = let inline seq (items: IComparable seq): IComparable seq = Seq.filter (fun x -> match x with | :? int -> true | _ -> false) items (Seq.compareWith Operators.compare (seq a) (seq b)) = 0 let compareBuilder (a: IComparable seq) (b: IComparable seq) = let inline seq (items: IComparable seq) = seq { for item in items do match item with | :? int -> yield item | _ -> () } (Seq.compareWith Operators.compare (seq a) (seq b)) = 0
Ayrat
хотя. там один вызов, все равно один раз енумератор вызывается
gsomix
@Dolfik @omgszer Нигде не ошибся? let compare (a: IComparable seq) (b: IComparable seq): bool = use aEnum = a.GetEnumerator() use bEnum = b.GetEnumerator() let rec go() = let aOpt = getNext<int> aEnum let bOpt = getNext<int> bEnum match aOpt, bOpt with | ValueNone, _ | _, ValueNone -> false | ValueSome ai, ValueSome bi -> let res = Operators.compare ai bi if res <> 0 then false else go() go()
Ayrat
последний иф вроде можно заменить на res = 0 && go()
Vasily
Ну вот да
Ayrat
и он по идее должен остаться хвостовым вызовом
Ayrat
но да, нормас и даже без мутабл
Vladimir
А че не Seq.compareWith ?
gsomix
gsomix
вчитавшись в код я понял что ты чекаешь равенство интовых подпоследовательностей в двух последовательностях
Vasily
Я так понимаю, Коля оптимизирует фабулосовский цикл диффа
Vladimir
filter + compareWith
а, понял)
Nikolay
Вот кстати айрат 2 это без анбоксинга, просто всегда возвращается элемент
Nikolay
А массивы сравниваются около 2мс
Ilya
у вас тут всё под контролем? а то сравнение 2 енумераблов требует станцевать гопака :)
Nikolay
Возможно там проход с двух сторон 🤔
Ilya
Иди отсюда, мальчик, не мешай взрослым дядям
переживаю просто за здоровье Николая
Nikolay
Я так понимаю, Коля оптимизирует фабулосовский цикл диффа
Нет, это так называемые модификаторы, что-то вроде аттачед пропертей в XF
Nikolay
переживаю просто за здоровье Николая
Я в отпуск скоро (надеюсь)
gsomix
Nikolay
А когда? Надолго?
Следующую неделю работаю, и в отпуск до 1 марта
Nikolay
Пора уже за три года
Ayrat
Пора уже за три года
тебе наконец паспорт отдали? поздравляю!!1
Nikolay
Nikolay
@gsomix поздравляю
Nikolay
Если что, у гсомикса с анбоксингом
Mikhαil
Паспорт на руках
Mikhαil
Наручники тоже
Mikhαil
gsomix
@gsomix поздравляю
Можно идти спать.
Ilya
@gsomix поздравляю
SequenceEqual ещё проверь
Vasily
Но самый быстрый почему-то ArrayEquals
Nikolay
Кажись с анбоксингом где-то накосячил, почему-то памяти больше
Ayrat
Ayrat
там кастов нет
Nikolay
Но самый быстрый почему-то ArrayEquals
Потому, что с ним ты можешь идти одновременно с начала и с конца
Nikolay
там кастов нет
Касты я убрал
Vasily
А, ну без кастов пизда рулю
Nikolay
пащиму
AyatNoUnboxing это без кастов
Vasily
Тогда вариант гсомикса самый быстрый, да
Nikolay
Nikolay
А arrayequals просто: for i in 0 .. (array.Length / 2) - 1 do и погнали
Ayrat
что это за код вообще
Ayrat
O_O
Ayrat
но это просто выбор первого
Nikolay
Да
Ayrat
это Seq.tryHead
Nikolay
Так как в бенчах все равно объекты одного типа
Nikolay
Поэтому условие всегда истино
Ayrat
Так как в бенчах все равно объекты одного типа
так ты бы более реальный бенч сделал чтобы мерять что-то реальное
Nikolay
И я немножко упростил компилятору
Ayrat
ну там гетерогенный массив с интами вперемешку
Ayrat
если надо мерять реальный кейс
Igor
какие-то странные результаты
Igor
у меня вот так