#benchmarkdotnet — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #benchmarkdotnet, aggregated by home.social.
-
Бенчмаркая Regex: конструктор показал 10 мкс, первый вызов — 1307
Проверить строку регулярным выражением в .NET можно по-разному, но совет всегда один: включите RegexOptions.Compiled или возьмите генератор. Замеры это подтверждают. А вот подготовка выражения оказалась не там, где её меряют: конструктор занимает 10 микросекунд, а первая же проверка на этом объекте — ещё 1307. Разобрался, куда уходит разница, и заодно нашёл границу, на которой статический Regex.IsMatch резко замедляется.
https://habr.com/ru/articles/1063204/
#regex #generatedregex #regexoptions #benchmarkdotnet #jit #кэш #производительность #регулярные_выражения #net_10 #string
-
Бенчмаркая Regex: конструктор показал 10 мкс, первый вызов — 1307
Проверить строку регулярным выражением в .NET можно по-разному, но совет всегда один: включите RegexOptions.Compiled или возьмите генератор. Замеры это подтверждают. А вот подготовка выражения оказалась не там, где её меряют: конструктор занимает 10 микросекунд, а первая же проверка на этом объекте — ещё 1307. Разобрался, куда уходит разница, и заодно нашёл границу, на которой статический Regex.IsMatch резко замедляется.
https://habr.com/ru/articles/1063204/
#regex #generatedregex #regexoptions #benchmarkdotnet #jit #кэш #производительность #регулярные_выражения #net_10 #string
-
Бенчмаркая Regex: конструктор показал 10 мкс, первый вызов — 1307
Проверить строку регулярным выражением в .NET можно по-разному, но совет всегда один: включите RegexOptions.Compiled или возьмите генератор. Замеры это подтверждают. А вот подготовка выражения оказалась не там, где её меряют: конструктор занимает 10 микросекунд, а первая же проверка на этом объекте — ещё 1307. Разобрался, куда уходит разница, и заодно нашёл границу, на которой статический Regex.IsMatch резко замедляется.
https://habr.com/ru/articles/1063204/
#regex #generatedregex #regexoptions #benchmarkdotnet #jit #кэш #производительность #регулярные_выражения #net_10 #string
-
Бенчмаркая FrozenDictionary: заменил Dictionary — получил от ×0,76 до ×1,9
FrozenDictionary сделан под словари, которые заполняют один раз при старте, а дальше только читают. Замерил на четырёх машинах и трёх рантаймах — разброс вышел от ×0,76 до ×1,9, и зависит он не от версии .NET, а от того, сколько ключей и как они устроены. Разобрал, куда уходит время в поиске по строке, вытащил из рантайма имена реализаций, которые он подбирает под конкретный набор ключей, и посмотрел в дизасме, за счёт чего Frozen выигрывает — и почему на маленьких наборах проигрывает.
https://habr.com/ru/articles/1063034/
#frozendictionary #dictionary #immutabledictionary #readonlydictionary #benchmarkdotnet #gethashcode #коллекции #производительность #net_10 #switch
-
Бенчмаркая ключи Dictionary: забыл IEquatable — получил ×5 и 96 байт на каждый поиск
Структура в роли ключа Dictionary — частый случай. Забыл IEquatable — и каждый TryGetValue в 4,4–5,7 раза медленнее, плюс 96 байт в куче на каждый поиск. Проверил на четырёх машинах и трёх рантаймах, снял дизасм FindValue и разобрал, откуда берутся ровно три упаковки, почему override Equals не спасает и при чём тут хэш record struct. Сам рантайм этот разрыв не закроет — и это не баг.
https://habr.com/ru/articles/1062854/
#dictionary #iequatable #boxing #боксинг #record_struct #benchmarkdotnet #gethashcode #производительность #net_10 #structs
-
Бенчмаркая ключи Dictionary: забыл IEquatable — получил ×5 и 96 байт на каждый поиск
Структура в роли ключа Dictionary — частый случай. Забыл IEquatable — и каждый TryGetValue в 4,4–5,7 раза медленнее, плюс 96 байт в куче на каждый поиск. Проверил на четырёх машинах и трёх рантаймах, снял дизасм FindValue и разобрал, откуда берутся ровно три упаковки, почему override Equals не спасает и при чём тут хэш record struct. Сам рантайм этот разрыв не закроет — и это не баг.
https://habr.com/ru/articles/1062854/
#dictionary #iequatable #boxing #боксинг #record_struct #benchmarkdotnet #gethashcode #производительность #net_10 #structs
-
Бенчмаркая ключи Dictionary: забыл IEquatable — получил ×5 и 96 байт на каждый поиск
Структура в роли ключа Dictionary — частый случай. Забыл IEquatable — и каждый TryGetValue в 4,4–5,7 раза медленнее, плюс 96 байт в куче на каждый поиск. Проверил на четырёх машинах и трёх рантаймах, снял дизасм FindValue и разобрал, откуда берутся ровно три упаковки, почему override Equals не спасает и при чём тут хэш record struct. Сам рантайм этот разрыв не закроет — и это не баг.
https://habr.com/ru/articles/1062854/
#dictionary #iequatable #boxing #боксинг #record_struct #benchmarkdotnet #gethashcode #производительность #net_10 #structs
-
Бенчмаркая регресс 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, и в комментах закономерный вопрос: обновляться на десятку или ждать одиннадцатую.
https://habr.com/ru/articles/1060518/
#benchmarkdotnet #linq #first #регресс #net_10 #jit #pgo #инлайнинг #производительность #osr
-
Бенчмаркая регресс 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, и в комментах закономерный вопрос: обновляться на десятку или ждать одиннадцатую.
https://habr.com/ru/articles/1060518/
#benchmarkdotnet #linq #first #регресс #net_10 #jit #pgo #инлайнинг #производительность #osr
-
Бенчмаркая регресс 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, и в комментах закономерный вопрос: обновляться на десятку или ждать одиннадцатую.
https://habr.com/ru/articles/1060518/
#benchmarkdotnet #linq #first #регресс #net_10 #jit #pgo #инлайнинг #производительность #osr
-
Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7
Уважаемые читатели, в этой статье я хочу рассказать о том, что происходит внутри values.Sum() в современном .NET — там нашлись векторные инструкции, контроль переполнения и список процессоров, которым рантайм намеренно ограничивает ширину вектора, — и представить свои выводы. В прошлых статьях серии самописные циклы уже проигрывали BCL в поиске по строке , JIT сам выкидывал проверки границ , а foreach прятал аллокации . Тут случай интереснее: values.Sum() — это LINQ, который при оптимизации первым делом меняют на цикл.
https://habr.com/ru/articles/1060470/
#benchmarkdotnet #linq #sum #simd #avx512 #векторизация #производительность #jit #ryujit #overflowexception
-
Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7
Уважаемые читатели, в этой статье я хочу рассказать о том, что происходит внутри values.Sum() в современном .NET — там нашлись векторные инструкции, контроль переполнения и список процессоров, которым рантайм намеренно ограничивает ширину вектора, — и представить свои выводы. В прошлых статьях серии самописные циклы уже проигрывали BCL в поиске по строке , JIT сам выкидывал проверки границ , а foreach прятал аллокации . Тут случай интереснее: values.Sum() — это LINQ, который при оптимизации первым делом меняют на цикл.
https://habr.com/ru/articles/1060470/
#benchmarkdotnet #linq #sum #simd #avx512 #векторизация #производительность #jit #ryujit #overflowexception
-
Бенчмаркая Sum: ускорил циклом — замедлил в ×4,7
Уважаемые читатели, в этой статье я хочу рассказать о том, что происходит внутри values.Sum() в современном .NET — там нашлись векторные инструкции, контроль переполнения и список процессоров, которым рантайм намеренно ограничивает ширину вектора, — и представить свои выводы. В прошлых статьях серии самописные циклы уже проигрывали BCL в поиске по строке , JIT сам выкидывал проверки границ , а foreach прятал аллокации . Тут случай интереснее: values.Sum() — это LINQ, который при оптимизации первым делом меняют на цикл.
https://habr.com/ru/articles/1060470/
#benchmarkdotnet #linq #sum #simd #avx512 #векторизация #производительность #jit #ryujit #overflowexception
-
Бенчмаркая поиск по строке: самописные циклы проигрывают от ×14 до ×154
Уважаемые читатели, в этой статье я хочу рассказать про поиск по строке и представить свои выводы. Началось с оптимизации: сравнил поиск символа циклом со string.IndexOf — и получил разницу в разы. Заодно выяснилось, что серверный Xeon с AVX-512 в этой задаче медленнее игрового десктопа с AVX2. Ниже разбор обоих фактов с дизасмом и замерами. Будет четыре истории, и в каждой — вопрос, на который я искал ответ:
https://habr.com/ru/articles/1059624/
#simd #avx2 #avx512 #benchmarkdotnet #indexof #searchvalues #ryujit #дизасм #производительность #бенчмарк
-
Бенчмаркая поиск по строке: самописные циклы проигрывают от ×14 до ×154
Уважаемые читатели, в этой статье я хочу рассказать про поиск по строке и представить свои выводы. Началось с оптимизации: сравнил поиск символа циклом со string.IndexOf — и получил разницу в разы. Заодно выяснилось, что серверный Xeon с AVX-512 в этой задаче медленнее игрового десктопа с AVX2. Ниже разбор обоих фактов с дизасмом и замерами. Будет четыре истории, и в каждой — вопрос, на который я искал ответ:
https://habr.com/ru/articles/1059624/
#simd #avx2 #avx512 #benchmarkdotnet #indexof #searchvalues #ryujit #дизасм #производительность #бенчмарк
-
Бенчмаркая поиск по строке: самописные циклы проигрывают от ×14 до ×154
Уважаемые читатели, в этой статье я хочу рассказать про поиск по строке и представить свои выводы. Началось с оптимизации: сравнил поиск символа циклом со string.IndexOf — и получил разницу в разы. Заодно выяснилось, что серверный Xeon с AVX-512 в этой задаче медленнее игрового десктопа с AVX2. Ниже разбор обоих фактов с дизасмом и замерами. Будет четыре истории, и в каждой — вопрос, на который я искал ответ:
https://habr.com/ru/articles/1059624/
#simd #avx2 #avx512 #benchmarkdotnet #indexof #searchvalues #ryujit #дизасм #производительность #бенчмарк
-
Бенчмаркая проверки границ: фикс, который шёл 8 лет, и проверка, которая жива до сих пор
Уважаемые читатели, в этой статье я хочу рассказать о проверках границ массива и представить свои выводы. Каждое обращение arr[i] обязано проверить индекс, иначе IndexOutOfRangeException — а JIT старается эти проверки убирать, когда может доказать, что выход за границы невозможен. Я взял несколько обычных циклов и посмотрел в машинный код на .net 8, 9, 10 и 11 одновременно. Результат разложился по версиям так, как я не ожидал. Будет три истории:
https://habr.com/ru/articles/1059040/
#benchmarkdotnet #JIT #bounds_check #проверка_границ #RyuJIT #NET_11 #дизассемблирование #производительность #оптимизация #массивы
-
Бенчмаркая проверки границ: фикс, который шёл 8 лет, и проверка, которая жива до сих пор
Уважаемые читатели, в этой статье я хочу рассказать о проверках границ массива и представить свои выводы. Каждое обращение arr[i] обязано проверить индекс, иначе IndexOutOfRangeException — а JIT старается эти проверки убирать, когда может доказать, что выход за границы невозможен. Я взял несколько обычных циклов и посмотрел в машинный код на .net 8, 9, 10 и 11 одновременно. Результат разложился по версиям так, как я не ожидал. Будет три истории:
https://habr.com/ru/articles/1059040/
#benchmarkdotnet #JIT #bounds_check #проверка_границ #RyuJIT #NET_11 #дизассемблирование #производительность #оптимизация #массивы
-
Бенчмаркая проверки границ: фикс, который шёл 8 лет, и проверка, которая жива до сих пор
Уважаемые читатели, в этой статье я хочу рассказать о проверках границ массива и представить свои выводы. Каждое обращение arr[i] обязано проверить индекс, иначе IndexOutOfRangeException — а JIT старается эти проверки убирать, когда может доказать, что выход за границы невозможен. Я взял несколько обычных циклов и посмотрел в машинный код на .net 8, 9, 10 и 11 одновременно. Результат разложился по версиям так, как я не ожидал. Будет три истории:
https://habr.com/ru/articles/1059040/
#benchmarkdotnet #JIT #bounds_check #проверка_границ #RyuJIT #NET_11 #дизассемблирование #производительность #оптимизация #массивы
-
Бенчмаркая foreach и энумераторы: аллокации, которые прятались 10 лет
Уважаемые читатели, в этой статье я хочу рассказать о скрытых аллокациях в обычном foreach и представить свои выводы. Тесты сделаны на .net 8, .net 9 и .net 10 одновременно, чтобы было видно, как одна и та же строчка кода ведет себя на разных рантаймах. Все тесты сделаны с использованием BenchmarkDotNet, полный код представлен на гите, так что каждый может проверить результаты и сделать свои выводы. Будет три истории, и все три про foreach:
https://habr.com/ru/articles/1058160/
#benchmarkdotnet #foreach #boxing #аллокации #GC #JIT #escape_analysis #NET_10 #производительность #SortedList
-
Бенчмаркая foreach и энумераторы: аллокации, которые прятались 10 лет
Уважаемые читатели, в этой статье я хочу рассказать о скрытых аллокациях в обычном foreach и представить свои выводы. Тесты сделаны на .net 8, .net 9 и .net 10 одновременно, чтобы было видно, как одна и та же строчка кода ведет себя на разных рантаймах. Все тесты сделаны с использованием BenchmarkDotNet, полный код представлен на гите, так что каждый может проверить результаты и сделать свои выводы. Будет три истории, и все три про foreach:
https://habr.com/ru/articles/1058160/
#benchmarkdotnet #foreach #boxing #аллокации #GC #JIT #escape_analysis #NET_10 #производительность #SortedList
-
Бенчмаркая foreach и энумераторы: аллокации, которые прятались 10 лет
Уважаемые читатели, в этой статье я хочу рассказать о скрытых аллокациях в обычном foreach и представить свои выводы. Тесты сделаны на .net 8, .net 9 и .net 10 одновременно, чтобы было видно, как одна и та же строчка кода ведет себя на разных рантаймах. Все тесты сделаны с использованием BenchmarkDotNet, полный код представлен на гите, так что каждый может проверить результаты и сделать свои выводы. Будет три истории, и все три про foreach:
https://habr.com/ru/articles/1058160/
#benchmarkdotnet #foreach #boxing #аллокации #GC #JIT #escape_analysis #NET_10 #производительность #SortedList
-
Аллокации, которых нет в коде: охота на скрытый боксинг в .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.
https://habr.com/ru/articles/1049236/
#NET_10 #c# #боксинг #boxing #аллокации #GC #BenchmarkDotNet #JIT
-
Аллокации, которых нет в коде: охота на скрытый боксинг в .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.
https://habr.com/ru/articles/1049236/
#NET_10 #c# #боксинг #boxing #аллокации #GC #BenchmarkDotNet #JIT
-
Аллокации, которых нет в коде: охота на скрытый боксинг в .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.
https://habr.com/ru/articles/1049236/
#NET_10 #c# #боксинг #boxing #аллокации #GC #BenchmarkDotNet #JIT
-
Which of these two is faster?
Read more here:
https://bgh.st/0p4n56 -
Which of these two is faster?
Read more here:
https://bgh.st/0p4n56 -
We all know that we're not supposed to use reflection in performance critical paths...
Read more here:
https://www.devleader.ca/2024/03/17/constructorinfo-how-to-make-reflection-in-dotnet-faster-for-instantiation/ -
We all know that we're not supposed to use reflection in performance critical paths...
Read more here:
https://www.devleader.ca/2024/03/17/constructorinfo-how-to-make-reflection-in-dotnet-faster-for-instantiation/ -
Which of these two is faster?
Read more here:
https://www.devleader.ca/2024/03/14/activator-createinstance-vs-type-invokemember-a-clear-winner/ -
Which of these two is faster?
Read more here:
https://www.devleader.ca/2024/03/14/activator-createinstance-vs-type-invokemember-a-clear-winner/ -
We all know that we're not supposed to use reflection in performance critical paths...
Read more here:
https://www.devleader.ca/2024/03/17/constructorinfo-how-to-make-reflection-in-dotnet-faster-for-instantiation/ -
We all know that we're not supposed to use reflection in performance critical paths...
Read more here:
https://www.devleader.ca/2024/03/17/constructorinfo-how-to-make-reflection-in-dotnet-faster-for-instantiation/ -
Which of these two is faster?
Read more here:
https://www.devleader.ca/2024/03/14/activator-createinstance-vs-type-invokemember-a-clear-winner/ -
Which of these two is faster?
Read more here:
https://www.devleader.ca/2024/03/14/activator-createinstance-vs-type-invokemember-a-clear-winner/ -
【C#】同じ機能、違う書き方 - パフォーマンスで選ぶべきコードはどっち?
https://qiita.com/Sakai_path/items/c51030f1291839025263?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items -
Validate Code Improvements With #BenchmarkDotNet - #dotNet
https://improveandrepeat.com/2025/03/validate-code-improvements-with-benchmarkdotnet/
-
Validate Code Improvements With #BenchmarkDotNet - #dotNet
https://improveandrepeat.com/2025/03/validate-code-improvements-with-benchmarkdotnet/
-
We all know that we're not supposed to use reflection in performance critical paths...
Read more in this post:
https://www.devleader.ca/2024/03/17/constructorinfo-how-to-make-reflection-in-dotnet-faster-for-instantiation/ -
We all know that we're not supposed to use reflection in performance critical paths...
Read more in this post:
https://www.devleader.ca/2024/03/17/constructorinfo-how-to-make-reflection-in-dotnet-faster-for-instantiation/ -
Which of these two is faster?
Read more in this post:
https://www.devleader.ca/2024/03/14/activator-createinstance-vs-type-invokemember-a-clear-winner/ -
Which of these two is faster?
Read more in this post:
https://www.devleader.ca/2024/03/14/activator-createinstance-vs-type-invokemember-a-clear-winner/ -
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
https://github.com/dotnet/performance/blob/main/src/tools/ResultsComparer/README.md
-
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
https://github.com/dotnet/performance/blob/main/src/tools/ResultsComparer/README.md
-
We all know that we're not supposed to use reflection in performance critical paths...
Read more in this post:
https://www.devleader.ca/2024/03/17/constructorinfo-how-to-make-reflection-in-dotnet-faster-for-instantiation/ -
We all know that we're not supposed to use reflection in performance critical paths...
Read more in this post:
https://www.devleader.ca/2024/03/17/constructorinfo-how-to-make-reflection-in-dotnet-faster-for-instantiation/ -
Which of these two is faster?
Read more in this post:
https://www.devleader.ca/2024/03/14/activator-createinstance-vs-type-invokemember-a-clear-winner/ -
Which of these two is faster?
Read more in this post:
https://www.devleader.ca/2024/03/14/activator-createinstance-vs-type-invokemember-a-clear-winner/ -
@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 (https://github.com/itinero) can benefit greatly from using #BenchmarkDotnet I just don't know where to start and how...
-
@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 (https://github.com/itinero) can benefit greatly from using #BenchmarkDotnet I just don't know where to start and how...