Nikolay
Ну акка сложнее, мб для неё это норм
Vladislav
Айратом
Nikolay
Кстати, гопак и процессор получается по скорости одинаково что-ли?
Vladislav
Кстати
Ayrat
ты ещё не понял что тут время иррелевантно
Ayrat
потому что мы не ждём обработки сообщений
Ayrat
прошла секунда и… может обработаться 1 сообзение, а может 10000
Ayrat
мы ж не ждём
Vladimir
let loop2 mailbox = Mailbox.take mailbox >>- fun someResult -> someResult |> Job.foreverServer |> start
кстати тут хэндлер выходит синхронный, а если мне надо асинхронный?
Vladislav
Как сайм же запушит в новый фшарп стейт машины то мейлбокс будет меньше жрать из-за того что он на асинках
Ayrat
Аахахаха
Vladislav
Которые билдер
Ayrat
>>= fun someResult -> Job.return someResult
Vladimir
>>=
я к тому что там будет асинк внутри, мб весь перф убъется
Ayrat
Ну тут 1.3 сек
это скорость заполнения очереди мейлбокса и всё
Ayrat
короче, вот код https://gist.github.com/Szer/61edbbf0185a5f6d974ccdff309f52ce
Ayrat
акку лучше выключайте, да
Vladimir
ну не, нарисуй сценарий
вот) следующие 400 строк это то что будет внутри хэндлера) https://github.com/fsharplang-ru/pulsar-client-dotnet/blob/develop/src/Pulsar.Client/Internal/ConsumerImpl.fs#L542
Nikolay
это скорость заполнения очереди мейлбокса и всё
Ну это да, надо наверное один эвэйт сделать
Nikolay
В конце
Ayrat
Ну это да, надо наверное один эвэйт сделать
тебе надо дождаться ответа на последнее сообщение
Nikolay
Ну да
Vladimir
ну мне нужно что-то для бенча
ну для бенча например сделай - каждое 10е сообщение чтобы требовало Task.Yeild() |> Async.AwaitTask
Vladimir
т.е. мэтч из двух сообщений, одно требует синхронной обработки их 9 из 10, одно требует асинхронной
Ayrat
Ну да
у тебя там ещё и рандомным посылается же. надо всех дожидаться
Ayrat
короче, бенч у тебя так себе
Nikolay
короче, бенч у тебя так себе
Я тестил тот кейс, который у меня будет)
Vladimir
блин, ну это писать надо...
лан, мб су самого руки дойдут, не парься)
Ayrat
Я тестил тот кейс, который у меня будет)
ну ты тестил его на мемори футпринт. Скорость тебе тут нельзя замерять
Nikolay
Меня как раз память волнует больше
Nikolay
Я подозревал, что оно меня сожрёт
Vasily
Пример с аккой нерелевантный, кстати
Vasily
Там надо роутер делать
Nikolay
Надо сесть и написать всё же мейлбокс свой
Nikolay
Не жрущий
Ayrat
лан, мб су самого руки дойдут, не парься)
[<Benchmark>] member this.FSharpMb () = let rec loop (inbox: MailboxProcessor<_>) = async { match! inbox.Receive() with | i when i%10 = 0 -> do! Async.SwitchToThreadPool() return! loop inbox | _ -> return! loop inbox } let processors = [| for _ in 1..100_000 -> MailboxProcessor.Start loop |] let msgCount = 1_000_000 let random = Random msgCount for i=0 to msgCount do let t = random.Next(0, 100_000 - 1) let mb = processors.[t] mb.Post(i) [<Benchmark>] member this.HopacMb () = let loop (mailbox: Hopac.Mailbox<_>) = job { match! mailbox with | i when i%10 = 0 -> do! Job.Scheduler.switchToWorker() return () | _ -> () } |> Job.foreverServer |> start let processors = [| for _ in 1..100_000 -> Hopac.Mailbox() |] Array.iter loop processors let msgCount = 1_000_000 let random = Random msgCount for i=0 to msgCount do let t = random.Next(0, 100_000 - 1) let mb = processors.[t] mb *<<+ i |> start
Ayrat
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | |--------- |--------:|---------:|---------:|----------:|----------:|------:|-----------:| | FSharpMb | 1.679 s | 0.2461 s | 0.2302 s | 3000.0000 | 1000.0000 | - | 1018.23 MB | | HopacMb | 1.787 s | 0.1032 s | 0.0966 s | 1000.0000 | - | - | 167.56 MB |
Ayrat
опять же, тут нет ожидания.
Ayrat
надо вообще убрать эти гейские 1000000 мейлбоксов
Nikolay
Там пишут что мейлбоксы лёгкие и быстрые
Nikolay
Это обман чтобы набрать классы
Nikolay
Мейлбокс процессоры
Nikolay
опять же, тут нет ожидания.
Вот интересно что по ожиданию будет
Nikolay
Надо попробовать ченел
Vladimir
опять же, тут нет ожидания.
надо чтобы работа одинаковая была в обоих случаях) а то может Async.SwitchToThreadPool() хуже чем Job.Scheduler.switchToWorker()
Vasily
Надо попробовать ченел
Ну можно сделать на System.Threading.Channels и посмотреть, что будет
Ayrat
ну я сделал 1, чтобы не мучаться
Ayrat
ща посмотрим, пару минут
Ayrat
[<Benchmark>] member this.FSharpMb () = let tcs = TaskCompletionSource() let msgCount = 1_000_000_000 let rec loop (inbox: MailboxProcessor<_>) = async { match! inbox.Receive() with | i when i = msgCount -> tcs.SetResult(()) | i when i%10 = 0 -> do! Async.SwitchToThreadPool() return! loop inbox | _ -> return! loop inbox } let processor = MailboxProcessor.Start loop for i=0 to msgCount do processor.Post(i) tcs.Task.Result [<Benchmark>] member this.HopacMb () = let msgCount = 1_000_000_000 let ivar = IVar() let loop (mailbox: Hopac.Mailbox<_>) = job { match! mailbox with | i when i = msgCount -> do! ivar *<= () | i when i%10 = 0 -> do! Job.Scheduler.switchToWorker() return () | _ -> () } |> Job.foreverServer |> start let processor = Hopac.Mailbox() loop processor for i=0 to msgCount do processor *<<+ i |> start run ivar
Vladimir
100 чтобы пока один отдыхал другие работали)
Ayrat
вот код на растерзание общественности
Ayrat
хз, дождёмся ли. Меня тут с детьми выгоняют гулять
Ayrat
чот даже первый ран на асинках не кончился
Vladimir
мильярд?!)
Ayrat
сделал поменьше!
Ayrat
всё, пошло
Vladimir
Ayrat
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | |--------- |---------:|---------:|---------:|----------:|----------:|----------:|----------:| | FSharpMb | 347.1 ms | 12.78 ms | 11.96 ms | 4000.0000 | 1000.0000 | 1000.0000 | 494.79 MB | | HopacMb | 245.7 ms | 8.37 ms | 7.83 ms | 1000.0000 | - | - | 168.62 MB |
Ayrat
let msgCount = 1_000_000 [<Benchmark>] member this.FSharpMb () = let tcs = TaskCompletionSource() let rec loop (inbox: MailboxProcessor<_>) = async { match! inbox.Receive() with | i when i = msgCount -> tcs.SetResult(()) | i when i%10 = 0 -> do! Async.SwitchToThreadPool() return! loop inbox | _ -> return! loop inbox } let processor = MailboxProcessor.Start loop for i=0 to msgCount do processor.Post(i) tcs.Task.Result [<Benchmark>] member this.HopacMb () = let ivar = IVar() let loop (mailbox: Hopac.Mailbox<_>) = job { match! mailbox with | i when i = msgCount -> do! ivar *<= () | i when i%10 = 0 -> do! Job.Scheduler.switchToWorker() return () | _ -> () } |> Job.foreverServer |> start let processor = Hopac.Mailbox() loop processor for i=0 to msgCount do processor *<<+ i |> start run ivar
Ayrat
всё, выгоняют из дома\
Ayrat
чо хотите с этим, то и делайте
Vladimir
CU
Nikolay
Nikolay
member x.Channel() = let mailbox () = let chan = Channel.CreateUnbounded<unit>() let rec loop () = async { do! chan.Reader.ReadAsync().AsTask() |> Async.AwaitTask return! loop () } loop () |> Async.StartImmediate chan let processors = [| for _ in 0 .. 100_000 -> mailbox () |] let messagesCount = 1_000_000 let random = Random(messagesCount) for i in 0 .. messagesCount do let t = random.Next(0, 100_000 - 1) let mailbox = processors.[t] mailbox.Writer.WriteAsync(()) |> ignore
Nikolay
Наговнякал
Nikolay
Но чёт дико
Danil
Аллокаций на гиг, неплохо
Ayrat
Но чёт дико
Чот ты с ченелом не то сделал.
Nikolay
О, щас Вагиф ворвётся
Vagif
Но чёт дико
Тогда уж 1.. messageCount, 1.. 100 и т.п.
Nikolay
Тогда уж 1.. messageCount, 1.. 100 и т.п.
Ну это не сильно что-то поменяет, только выглядеть лучше будет