home.social

#benchmarkdotnet — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #benchmarkdotnet, aggregated by home.social.

  1. Бенчмаркая Regex: конструктор показал 10 мкс, первый вызов — 1307

    Проверить строку регулярным выражением в .NET можно по-разному, но совет всегда один: включите RegexOptions.Compiled или возьмите генератор. Замеры это подтверждают. А вот подготовка выражения оказалась не там, где её меряют: конструктор занимает 10 микросекунд, а первая же проверка на этом объекте — ещё 1307. Разобрался, куда уходит разница, и заодно нашёл границу, на которой статический Regex.IsMatch резко замедляется.

    habr.com/ru/articles/1063204/

    #regex #generatedregex #regexoptions #benchmarkdotnet #jit #кэш #производительность #регулярные_выражения #net_10 #string

  2. Бенчмаркая Regex: конструктор показал 10 мкс, первый вызов — 1307

    Проверить строку регулярным выражением в .NET можно по-разному, но совет всегда один: включите RegexOptions.Compiled или возьмите генератор. Замеры это подтверждают. А вот подготовка выражения оказалась не там, где её меряют: конструктор занимает 10 микросекунд, а первая же проверка на этом объекте — ещё 1307. Разобрался, куда уходит разница, и заодно нашёл границу, на которой статический Regex.IsMatch резко замедляется.

    habr.com/ru/articles/1063204/

    #regex #generatedregex #regexoptions #benchmarkdotnet #jit #кэш #производительность #регулярные_выражения #net_10 #string

  3. Бенчмаркая Regex: конструктор показал 10 мкс, первый вызов — 1307

    Проверить строку регулярным выражением в .NET можно по-разному, но совет всегда один: включите RegexOptions.Compiled или возьмите генератор. Замеры это подтверждают. А вот подготовка выражения оказалась не там, где её меряют: конструктор занимает 10 микросекунд, а первая же проверка на этом объекте — ещё 1307. Разобрался, куда уходит разница, и заодно нашёл границу, на которой статический Regex.IsMatch резко замедляется.

    habr.com/ru/articles/1063204/

    #regex #generatedregex #regexoptions #benchmarkdotnet #jit #кэш #производительность #регулярные_выражения #net_10 #string

  4. Бенчмаркая FrozenDictionary: заменил Dictionary — получил от ×0,76 до ×1,9

    FrozenDictionary сделан под словари, которые заполняют один раз при старте, а дальше только читают. Замерил на четырёх машинах и трёх рантаймах — разброс вышел от ×0,76 до ×1,9, и зависит он не от версии .NET, а от того, сколько ключей и как они устроены. Разобрал, куда уходит время в поиске по строке, вытащил из рантайма имена реализаций, которые он подбирает под конкретный набор ключей, и посмотрел в дизасме, за счёт чего Frozen выигрывает — и почему на маленьких наборах проигрывает.

    habr.com/ru/articles/1063034/

    #frozendictionary #dictionary #immutabledictionary #readonlydictionary #benchmarkdotnet #gethashcode #коллекции #производительность #net_10 #switch

  5. Бенчмаркая ключи Dictionary: забыл IEquatable — получил ×5 и 96 байт на каждый поиск

    Структура в роли ключа Dictionary — частый случай. Забыл IEquatable — и каждый TryGetValue в 4,4–5,7 раза медленнее, плюс 96 байт в куче на каждый поиск. Проверил на четырёх машинах и трёх рантаймах, снял дизасм FindValue и разобрал, откуда берутся ровно три упаковки, почему override Equals не спасает и при чём тут хэш record struct. Сам рантайм этот разрыв не закроет — и это не баг.

    habr.com/ru/articles/1062854/

    #dictionary #iequatable #boxing #боксинг #record_struct #benchmarkdotnet #gethashcode #производительность #net_10 #structs

  6. Бенчмаркая ключи Dictionary: забыл IEquatable — получил ×5 и 96 байт на каждый поиск

    Структура в роли ключа Dictionary — частый случай. Забыл IEquatable — и каждый TryGetValue в 4,4–5,7 раза медленнее, плюс 96 байт в куче на каждый поиск. Проверил на четырёх машинах и трёх рантаймах, снял дизасм FindValue и разобрал, откуда берутся ровно три упаковки, почему override Equals не спасает и при чём тут хэш record struct. Сам рантайм этот разрыв не закроет — и это не баг.

    habr.com/ru/articles/1062854/

    #dictionary #iequatable #boxing #боксинг #record_struct #benchmarkdotnet #gethashcode #производительность #net_10 #structs

  7. Бенчмаркая ключи Dictionary: забыл IEquatable — получил ×5 и 96 байт на каждый поиск

    Структура в роли ключа Dictionary — частый случай. Забыл IEquatable — и каждый TryGetValue в 4,4–5,7 раза медленнее, плюс 96 байт в куче на каждый поиск. Проверил на четырёх машинах и трёх рантаймах, снял дизасм FindValue и разобрал, откуда берутся ровно три упаковки, почему override Equals не спасает и при чём тут хэш record struct. Сам рантайм этот разрыв не закроет — и это не баг.

    habr.com/ru/articles/1062854/

    #dictionary #iequatable #boxing #боксинг #record_struct #benchmarkdotnet #gethashcode #производительность #net_10 #structs

  8. Бенчмаркая регресс LINQ: обещали −19%, на четырёх машинах намерил +31%

    Уважаемые читатели, в этой статье я хочу рассказать о проверке обещанного регресса LINQ в .NET 10 — и представить свои выводы. В dotnet/runtime с лета висит issue #117717 : после перехода на .NET 10 метод с First(предикат) просел к девятке — у автора issue на Intel 13-го поколения до 19%, у Энди Эйерса из JIT-команды на Zen 4 порядка 10%. Причину команда назвала сама: связка PGO и инлайнинга, делегат предиката перестал инлайниться. Решение тоже озвучили: в десятке чинить не будем — сломаем другое, переносим в .NET 11. Был частичный фикс ( PR #117816 ), после которого issue переоткрыли как #119425 . Десятка при этом LTS, и в комментах закономерный вопрос: обновляться на десятку или ждать одиннадцатую.

    habr.com/ru/articles/1060518/

    #benchmarkdotnet #linq #first #регресс #net_10 #jit #pgo #инлайнинг #производительность #osr

  9. Бенчмаркая регресс LINQ: обещали −19%, на четырёх машинах намерил +31%

    Уважаемые читатели, в этой статье я хочу рассказать о проверке обещанного регресса LINQ в .NET 10 — и представить свои выводы. В dotnet/runtime с лета висит issue #117717 : после перехода на .NET 10 метод с First(предикат) просел к девятке — у автора issue на Intel 13-го поколения до 19%, у Энди Эйерса из JIT-команды на Zen 4 порядка 10%. Причину команда назвала сама: связка PGO и инлайнинга, делегат предиката перестал инлайниться. Решение тоже озвучили: в десятке чинить не будем — сломаем другое, переносим в .NET 11. Был частичный фикс ( PR #117816 ), после которого issue переоткрыли как #119425 . Десятка при этом LTS, и в комментах закономерный вопрос: обновляться на десятку или ждать одиннадцатую.

    habr.com/ru/articles/1060518/

    #benchmarkdotnet #linq #first #регресс #net_10 #jit #pgo #инлайнинг #производительность #osr

  10. Бенчмаркая регресс LINQ: обещали −19%, на четырёх машинах намерил +31%

    Уважаемые читатели, в этой статье я хочу рассказать о проверке обещанного регресса LINQ в .NET 10 — и представить свои выводы. В dotnet/runtime с лета висит issue #117717 : после перехода на .NET 10 метод с First(предикат) просел к девятке — у автора issue на Intel 13-го поколения до 19%, у Энди Эйерса из JIT-команды на Zen 4 порядка 10%. Причину команда назвала сама: связка PGO и инлайнинга, делегат предиката перестал инлайниться. Решение тоже озвучили: в десятке чинить не будем — сломаем другое, переносим в .NET 11. Был частичный фикс ( PR #117816 ), после которого issue переоткрыли как #119425 . Десятка при этом LTS, и в комментах закономерный вопрос: обновляться на десятку или ждать одиннадцатую.

    habr.com/ru/articles/1060518/

    #benchmarkdotnet #linq #first #регресс #net_10 #jit #pgo #инлайнинг #производительность #osr

  11. Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7

    Уважаемые читатели, в этой статье я хочу рассказать о том, что происходит внутри values.Sum() в современном .NET — там нашлись векторные инструкции, контроль переполнения и список процессоров, которым рантайм намеренно ограничивает ширину вектора, — и представить свои выводы. В прошлых статьях серии самописные циклы уже проигрывали BCL в поиске по строке , JIT сам выкидывал проверки границ , а foreach прятал аллокации . Тут случай интереснее: values.Sum() — это LINQ, который при оптимизации первым делом меняют на цикл.

    habr.com/ru/articles/1060470/

    #benchmarkdotnet #linq #sum #simd #avx512 #векторизация #производительность #jit #ryujit #overflowexception

  12. Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7

    Уважаемые читатели, в этой статье я хочу рассказать о том, что происходит внутри values.Sum() в современном .NET — там нашлись векторные инструкции, контроль переполнения и список процессоров, которым рантайм намеренно ограничивает ширину вектора, — и представить свои выводы. В прошлых статьях серии самописные циклы уже проигрывали BCL в поиске по строке , JIT сам выкидывал проверки границ , а foreach прятал аллокации . Тут случай интереснее: values.Sum() — это LINQ, который при оптимизации первым делом меняют на цикл.

    habr.com/ru/articles/1060470/

    #benchmarkdotnet #linq #sum #simd #avx512 #векторизация #производительность #jit #ryujit #overflowexception

  13. Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7

    Уважаемые читатели, в этой статье я хочу рассказать о том, что происходит внутри values.Sum() в современном .NET — там нашлись векторные инструкции, контроль переполнения и список процессоров, которым рантайм намеренно ограничивает ширину вектора, — и представить свои выводы. В прошлых статьях серии самописные циклы уже проигрывали BCL в поиске по строке , JIT сам выкидывал проверки границ , а foreach прятал аллокации . Тут случай интереснее: values.Sum() — это LINQ, который при оптимизации первым делом меняют на цикл.

    habr.com/ru/articles/1060470/

    #benchmarkdotnet #linq #sum #simd #avx512 #векторизация #производительность #jit #ryujit #overflowexception

  14. Бенчмаркая поиск по строке: самописные циклы проигрывают от ×14 до ×154

    Уважаемые читатели, в этой статье я хочу рассказать про поиск по строке и представить свои выводы. Началось с оптимизации: сравнил поиск символа циклом со string.IndexOf — и получил разницу в разы. Заодно выяснилось, что серверный Xeon с AVX-512 в этой задаче медленнее игрового десктопа с AVX2. Ниже разбор обоих фактов с дизасмом и замерами. Будет четыре истории, и в каждой — вопрос, на который я искал ответ:

    habr.com/ru/articles/1059624/

    #simd #avx2 #avx512 #benchmarkdotnet #indexof #searchvalues #ryujit #дизасм #производительность #бенчмарк

  15. Бенчмаркая поиск по строке: самописные циклы проигрывают от ×14 до ×154

    Уважаемые читатели, в этой статье я хочу рассказать про поиск по строке и представить свои выводы. Началось с оптимизации: сравнил поиск символа циклом со string.IndexOf — и получил разницу в разы. Заодно выяснилось, что серверный Xeon с AVX-512 в этой задаче медленнее игрового десктопа с AVX2. Ниже разбор обоих фактов с дизасмом и замерами. Будет четыре истории, и в каждой — вопрос, на который я искал ответ:

    habr.com/ru/articles/1059624/

    #simd #avx2 #avx512 #benchmarkdotnet #indexof #searchvalues #ryujit #дизасм #производительность #бенчмарк

  16. Бенчмаркая поиск по строке: самописные циклы проигрывают от ×14 до ×154

    Уважаемые читатели, в этой статье я хочу рассказать про поиск по строке и представить свои выводы. Началось с оптимизации: сравнил поиск символа циклом со string.IndexOf — и получил разницу в разы. Заодно выяснилось, что серверный Xeon с AVX-512 в этой задаче медленнее игрового десктопа с AVX2. Ниже разбор обоих фактов с дизасмом и замерами. Будет четыре истории, и в каждой — вопрос, на который я искал ответ:

    habr.com/ru/articles/1059624/

    #simd #avx2 #avx512 #benchmarkdotnet #indexof #searchvalues #ryujit #дизасм #производительность #бенчмарк

  17. Бенчмаркая проверки границ: фикс, который шёл 8 лет, и проверка, которая жива до сих пор

    Уважаемые читатели, в этой статье я хочу рассказать о проверках границ массива и представить свои выводы. Каждое обращение arr[i] обязано проверить индекс, иначе IndexOutOfRangeException — а JIT старается эти проверки убирать, когда может доказать, что выход за границы невозможен. Я взял несколько обычных циклов и посмотрел в машинный код на .net 8, 9, 10 и 11 одновременно. Результат разложился по версиям так, как я не ожидал. Будет три истории:

    habr.com/ru/articles/1059040/

    #benchmarkdotnet #JIT #bounds_check #проверка_границ #RyuJIT #NET_11 #дизассемблирование #производительность #оптимизация #массивы

  18. Бенчмаркая проверки границ: фикс, который шёл 8 лет, и проверка, которая жива до сих пор

    Уважаемые читатели, в этой статье я хочу рассказать о проверках границ массива и представить свои выводы. Каждое обращение arr[i] обязано проверить индекс, иначе IndexOutOfRangeException — а JIT старается эти проверки убирать, когда может доказать, что выход за границы невозможен. Я взял несколько обычных циклов и посмотрел в машинный код на .net 8, 9, 10 и 11 одновременно. Результат разложился по версиям так, как я не ожидал. Будет три истории:

    habr.com/ru/articles/1059040/

    #benchmarkdotnet #JIT #bounds_check #проверка_границ #RyuJIT #NET_11 #дизассемблирование #производительность #оптимизация #массивы

  19. Бенчмаркая проверки границ: фикс, который шёл 8 лет, и проверка, которая жива до сих пор

    Уважаемые читатели, в этой статье я хочу рассказать о проверках границ массива и представить свои выводы. Каждое обращение arr[i] обязано проверить индекс, иначе IndexOutOfRangeException — а JIT старается эти проверки убирать, когда может доказать, что выход за границы невозможен. Я взял несколько обычных циклов и посмотрел в машинный код на .net 8, 9, 10 и 11 одновременно. Результат разложился по версиям так, как я не ожидал. Будет три истории:

    habr.com/ru/articles/1059040/

    #benchmarkdotnet #JIT #bounds_check #проверка_границ #RyuJIT #NET_11 #дизассемблирование #производительность #оптимизация #массивы

  20. Бенчмаркая foreach и энумераторы: аллокации, которые прятались 10 лет

    Уважаемые читатели, в этой статье я хочу рассказать о скрытых аллокациях в обычном foreach и представить свои выводы. Тесты сделаны на .net 8, .net 9 и .net 10 одновременно, чтобы было видно, как одна и та же строчка кода ведет себя на разных рантаймах. Все тесты сделаны с использованием BenchmarkDotNet, полный код представлен на гите, так что каждый может проверить результаты и сделать свои выводы. Будет три истории, и все три про foreach:

    habr.com/ru/articles/1058160/

    #benchmarkdotnet #foreach #boxing #аллокации #GC #JIT #escape_analysis #NET_10 #производительность #SortedList

  21. Бенчмаркая foreach и энумераторы: аллокации, которые прятались 10 лет

    Уважаемые читатели, в этой статье я хочу рассказать о скрытых аллокациях в обычном foreach и представить свои выводы. Тесты сделаны на .net 8, .net 9 и .net 10 одновременно, чтобы было видно, как одна и та же строчка кода ведет себя на разных рантаймах. Все тесты сделаны с использованием BenchmarkDotNet, полный код представлен на гите, так что каждый может проверить результаты и сделать свои выводы. Будет три истории, и все три про foreach:

    habr.com/ru/articles/1058160/

    #benchmarkdotnet #foreach #boxing #аллокации #GC #JIT #escape_analysis #NET_10 #производительность #SortedList

  22. Бенчмаркая foreach и энумераторы: аллокации, которые прятались 10 лет

    Уважаемые читатели, в этой статье я хочу рассказать о скрытых аллокациях в обычном foreach и представить свои выводы. Тесты сделаны на .net 8, .net 9 и .net 10 одновременно, чтобы было видно, как одна и та же строчка кода ведет себя на разных рантаймах. Все тесты сделаны с использованием BenchmarkDotNet, полный код представлен на гите, так что каждый может проверить результаты и сделать свои выводы. Будет три истории, и все три про foreach:

    habr.com/ru/articles/1058160/

    #benchmarkdotnet #foreach #boxing #аллокации #GC #JIT #escape_analysis #NET_10 #производительность #SortedList

  23. Аллокации, которых нет в коде: охота на скрытый боксинг в .NET 10

    Вы написали struct ради zero-allocation, прошли code review — а в проде Gen0-коллекции всё равно идут косяком. Самая дорогая аллокация та, которой нет в исходниках: компилятор молча упаковывает ваш value-тип в кучу там, где вы этого не просили. Разбираю, где скрытый боксинг живёт и на .NET 10 (интерфейс на struct, foreach по IEnumerable, ValueType.Equals, params object[], замыкания), а где рантайм его уже вырезал — и почему слепо чинить HasFlag по гайдам 2015 года вредно. Два прод-кейса, шпаргалка-таблица, бенчмарк на BenchmarkDotNet и охота на box через DOTNET_JitDisasm и dotnet-gcdump.

    habr.com/ru/articles/1049236/

    #NET_10 #c# #боксинг #boxing #аллокации #GC #BenchmarkDotNet #JIT

  24. Аллокации, которых нет в коде: охота на скрытый боксинг в .NET 10

    Вы написали struct ради zero-allocation, прошли code review — а в проде Gen0-коллекции всё равно идут косяком. Самая дорогая аллокация та, которой нет в исходниках: компилятор молча упаковывает ваш value-тип в кучу там, где вы этого не просили. Разбираю, где скрытый боксинг живёт и на .NET 10 (интерфейс на struct, foreach по IEnumerable, ValueType.Equals, params object[], замыкания), а где рантайм его уже вырезал — и почему слепо чинить HasFlag по гайдам 2015 года вредно. Два прод-кейса, шпаргалка-таблица, бенчмарк на BenchmarkDotNet и охота на box через DOTNET_JitDisasm и dotnet-gcdump.

    habr.com/ru/articles/1049236/

    #NET_10 #c# #боксинг #boxing #аллокации #GC #BenchmarkDotNet #JIT

  25. Аллокации, которых нет в коде: охота на скрытый боксинг в .NET 10

    Вы написали struct ради zero-allocation, прошли code review — а в проде Gen0-коллекции всё равно идут косяком. Самая дорогая аллокация та, которой нет в исходниках: компилятор молча упаковывает ваш value-тип в кучу там, где вы этого не просили. Разбираю, где скрытый боксинг живёт и на .NET 10 (интерфейс на struct, foreach по IEnumerable, ValueType.Equals, params object[], замыкания), а где рантайм его уже вырезал — и почему слепо чинить HasFlag по гайдам 2015 года вредно. Два прод-кейса, шпаргалка-таблица, бенчмарк на BenchmarkDotNet и охота на box через DOTNET_JitDisasm и dotnet-gcdump.

    habr.com/ru/articles/1049236/

    #NET_10 #c# #боксинг #boxing #аллокации #GC #BenchmarkDotNet #JIT

  26. TIL I can use the ResultComparer tool to prevent performance regression by integrating it into CI/CD in @danielmarbach’s talk on performance benchmarking at #NDCOslo. #BenchmarKDotNet #dotnet

    github.com/dotnet/performance/

  27. TIL I can use the ResultComparer tool to prevent performance regression by integrating it into CI/CD in @danielmarbach’s talk on performance benchmarking at #NDCOslo. #BenchmarKDotNet #dotnet

    github.com/dotnet/performance/

  28. @antaoalmada Thank you for writing and sharing this!

    I was wondering how this is supposed to be integrated in a real-world project? Do I refactor my code to make these micro benchmarks possible on the actual code base or do I just experiment and then let go?

    I think the Itinero route planner (github.com/itinero) can benefit greatly from using #BenchmarkDotnet I just don't know where to start and how...

  29. @antaoalmada Thank you for writing and sharing this!

    I was wondering how this is supposed to be integrated in a real-world project? Do I refactor my code to make these micro benchmarks possible on the actual code base or do I just experiment and then let go?

    I think the Itinero route planner (github.com/itinero) can benefit greatly from using #BenchmarkDotnet I just don't know where to start and how...