Сообщение Re[2]: dotnetBenchmark как готовить от 07.07.2020 17:41
Изменено 07.07.2020 19:53 okon
Re[2]: dotnetBenchmark как готовить
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, okon, Вы писали:
O>>Хотелось померять скорость вставки строки в разных сценариях с обычной строкой, билдер без выделенного заранее буффера и билдер с буффером.
O>>Если не настраивать параметры теста, то по умолчанию он начинает длинные танцы с бубном, я так и не дождался результата за 5 минут и не понятно когда ждать завершения — прервал.
S>Не очень понятно, что именно вы хотите измерить.
S>BDN предполагает, что замеряемая операция воспроизводима.
Хотелось задать строку определенной длины например 100 символов и посмотреть сколько будет стоить вставка строки в 1 символ.
S>Т.е. что-то типа "берём пустой stringbuilder и вставляем в него 100 символов по одному", сравниваем с "берём stringbuilder с capacity=100 и вставляем в него 100 символов по одному".
S>То, что у вас написано — это стрингбилдер инициализируется 1 раз, затем в него охулиард раз вставляется 1 символ.
Во как, я просто привык что в тестах обычно на каждый вызов метод создается новый экземпляр.
Тут видимо иначе, в документации я нашел пример с конструктором, но там не уточняется как этот экземпляр используется.
https://benchmarkdotnet.org/articles/overview.html
p.s. проверил экспериментально — да конструктор 1 раз вызывается на все замеры а не перед каждым замером, печально придется как-то обходить.
S>Понятно, что перформанс этой вставки зависит не от подробностей инициализации, а от посторонних вещей — типа пришлось ли сделать GC при перевыделении буфера во время именно этой вставки.
S>Я бы писал примерно так:
S>[cs]
S> [Benchmark]
S> public void InsertStringBuilderWithCapacity()
S> {
S> var stringBuilderWithCapacity = new StringBuilder(BaseStr.Length * RepeatCount + InsertCount);
S> stringBuilderWithCapacity.Append(GetString());
S> for(var i=0; i<InsertCount; i++)
S> stringBuilderWithCapacity.Insert(4, "5");
S> }
Да но в этом случае тест получается не совсем корректный — тут мы измеряем не только вставку но и создание экземпляра StringBuilder и копирование в него строки.
А хочется замерить только вставку в уже проинициализированный. Можно конечно создать дополнительные методы без вставки и сравнить время, но это как временный вариант — не уверен что это правильный способ.
S>Здравствуйте, okon, Вы писали:
O>>Хотелось померять скорость вставки строки в разных сценариях с обычной строкой, билдер без выделенного заранее буффера и билдер с буффером.
O>>Если не настраивать параметры теста, то по умолчанию он начинает длинные танцы с бубном, я так и не дождался результата за 5 минут и не понятно когда ждать завершения — прервал.
S>Не очень понятно, что именно вы хотите измерить.
S>BDN предполагает, что замеряемая операция воспроизводима.
Хотелось задать строку определенной длины например 100 символов и посмотреть сколько будет стоить вставка строки в 1 символ.
S>Т.е. что-то типа "берём пустой stringbuilder и вставляем в него 100 символов по одному", сравниваем с "берём stringbuilder с capacity=100 и вставляем в него 100 символов по одному".
S>То, что у вас написано — это стрингбилдер инициализируется 1 раз, затем в него охулиард раз вставляется 1 символ.
Во как, я просто привык что в тестах обычно на каждый вызов метод создается новый экземпляр.
Тут видимо иначе, в документации я нашел пример с конструктором, но там не уточняется как этот экземпляр используется.
https://benchmarkdotnet.org/articles/overview.html
p.s. проверил экспериментально — да конструктор 1 раз вызывается на все замеры а не перед каждым замером, печально придется как-то обходить.
S>Понятно, что перформанс этой вставки зависит не от подробностей инициализации, а от посторонних вещей — типа пришлось ли сделать GC при перевыделении буфера во время именно этой вставки.
S>Я бы писал примерно так:
S>[cs]
S> [Benchmark]
S> public void InsertStringBuilderWithCapacity()
S> {
S> var stringBuilderWithCapacity = new StringBuilder(BaseStr.Length * RepeatCount + InsertCount);
S> stringBuilderWithCapacity.Append(GetString());
S> for(var i=0; i<InsertCount; i++)
S> stringBuilderWithCapacity.Insert(4, "5");
S> }
Да но в этом случае тест получается не совсем корректный — тут мы измеряем не только вставку но и создание экземпляра StringBuilder и копирование в него строки.
А хочется замерить только вставку в уже проинициализированный. Можно конечно создать дополнительные методы без вставки и сравнить время, но это как временный вариант — не уверен что это правильный способ.
Re[2]: dotnetBenchmark как готовить
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, okon, Вы писали:
O>>Хотелось померять скорость вставки строки в разных сценариях с обычной строкой, билдер без выделенного заранее буффера и билдер с буффером.
O>>Если не настраивать параметры теста, то по умолчанию он начинает длинные танцы с бубном, я так и не дождался результата за 5 минут и не понятно когда ждать завершения — прервал.
S>Не очень понятно, что именно вы хотите измерить.
S>BDN предполагает, что замеряемая операция воспроизводима.
Хотелось задать строку определенной длины например 100 символов и посмотреть сколько будет стоить вставка строки в 1 символ.
S>Т.е. что-то типа "берём пустой stringbuilder и вставляем в него 100 символов по одному", сравниваем с "берём stringbuilder с capacity=100 и вставляем в него 100 символов по одному".
S>То, что у вас написано — это стрингбилдер инициализируется 1 раз, затем в него охулиард раз вставляется 1 символ.
Во как, я просто привык что в тестах обычно на каждый вызов метод создается новый экземпляр.
Тут видимо иначе, в документации я нашел пример с конструктором, но там не уточняется как этот экземпляр используется.
https://benchmarkdotnet.org/articles/overview.html
p.s. проверил экспериментально — да конструктор 1 раз вызывается на все замеры а не перед каждым замером, печально придется как-то обходить.
S>Понятно, что перформанс этой вставки зависит не от подробностей инициализации, а от посторонних вещей — типа пришлось ли сделать GC при перевыделении буфера во время именно этой вставки.
S>Я бы писал примерно так:
S>[cs]
S> [Benchmark]
S> public void InsertStringBuilderWithCapacity()
S> {
S> var stringBuilderWithCapacity = new StringBuilder(BaseStr.Length * RepeatCount + InsertCount);
S> stringBuilderWithCapacity.Append(GetString());
S> for(var i=0; i<InsertCount; i++)
S> stringBuilderWithCapacity.Insert(4, "5");
S> }
Да но в этом случае тест получается не совсем корректный — тут мы измеряем не только вставку но и создание экземпляра StringBuilder и копирование в него строки.
А хочется замерить только вставку в уже проинициализированный. Можно конечно создать дополнительные методы без вставки и сравнить время, но это как временный вариант — не уверен что это правильный способ.
p.s. попробовал сделать замер с методами инициализации и вставки получается тоже высокая погрешность и странности например метод InsertStringBuilder () меньше погрешность чем у метода InitStringBuilder (), хотя insert состоит из 2х частей такой же init и непосредственно операция вставки. Но есть и плюсы — метод Empty стал адекватнее измеряться.
S>Здравствуйте, okon, Вы писали:
O>>Хотелось померять скорость вставки строки в разных сценариях с обычной строкой, билдер без выделенного заранее буффера и билдер с буффером.
O>>Если не настраивать параметры теста, то по умолчанию он начинает длинные танцы с бубном, я так и не дождался результата за 5 минут и не понятно когда ждать завершения — прервал.
S>Не очень понятно, что именно вы хотите измерить.
S>BDN предполагает, что замеряемая операция воспроизводима.
Хотелось задать строку определенной длины например 100 символов и посмотреть сколько будет стоить вставка строки в 1 символ.
S>Т.е. что-то типа "берём пустой stringbuilder и вставляем в него 100 символов по одному", сравниваем с "берём stringbuilder с capacity=100 и вставляем в него 100 символов по одному".
S>То, что у вас написано — это стрингбилдер инициализируется 1 раз, затем в него охулиард раз вставляется 1 символ.
Во как, я просто привык что в тестах обычно на каждый вызов метод создается новый экземпляр.
Тут видимо иначе, в документации я нашел пример с конструктором, но там не уточняется как этот экземпляр используется.
https://benchmarkdotnet.org/articles/overview.html
p.s. проверил экспериментально — да конструктор 1 раз вызывается на все замеры а не перед каждым замером, печально придется как-то обходить.
S>Понятно, что перформанс этой вставки зависит не от подробностей инициализации, а от посторонних вещей — типа пришлось ли сделать GC при перевыделении буфера во время именно этой вставки.
S>Я бы писал примерно так:
S>[cs]
S> [Benchmark]
S> public void InsertStringBuilderWithCapacity()
S> {
S> var stringBuilderWithCapacity = new StringBuilder(BaseStr.Length * RepeatCount + InsertCount);
S> stringBuilderWithCapacity.Append(GetString());
S> for(var i=0; i<InsertCount; i++)
S> stringBuilderWithCapacity.Insert(4, "5");
S> }
Да но в этом случае тест получается не совсем корректный — тут мы измеряем не только вставку но и создание экземпляра StringBuilder и копирование в него строки.
А хочется замерить только вставку в уже проинициализированный. Можно конечно создать дополнительные методы без вставки и сравнить время, но это как временный вариант — не уверен что это правильный способ.
p.s. попробовал сделать замер с методами инициализации и вставки получается тоже высокая погрешность и странности например метод InsertStringBuilder () меньше погрешность чем у метода InitStringBuilder (), хотя insert состоит из 2х частей такой же init и непосредственно операция вставки. Но есть и плюсы — метод Empty стал адекватнее измеряться.
| Method | Job | InvocationCount | IterationCount | UnrollFactor | RepeatCount | BaseString | Mean | Error | StdDev | Median |
|-------------------------------- |--------- |---------------- |--------------- |------------- |------------ |----------- |------------:|--------------:|------------:|------------:|
| InsertStr | QuickJob | 100 | 5 | 1 | 10 | 1234567890 | 388.3000 ns | 80.3761 ns | 20.8734 ns | 398.5000 ns |
| InitStr | QuickJob | 100 | 5 | 1 | 10 | 1234567890 | 343.0000 ns | 94.7524 ns | 24.6069 ns | 342.0000 ns |
| InsertStringBuilder | QuickJob | 100 | 5 | 1 | 10 | 1234567890 | 504.2000 ns | 246.6427 ns | 64.0523 ns | 497.0000 ns |
| InitStringBuilder | QuickJob | 100 | 5 | 1 | 10 | 1234567890 | 691.1000 ns | 1,509.4735 ns | 392.0055 ns | 421.5000 ns |
| InsertStringBuilderWithCapacity | QuickJob | 100 | 5 | 1 | 10 | 1234567890 | 530.5000 ns | 322.6899 ns | 49.9366 ns | 516.5000 ns |
| InitStringBuilderWithCapacity | QuickJob | 100 | 5 | 1 | 10 | 1234567890 | 536.0000 ns | 462.2056 ns | 120.0333 ns | 525.0000 ns |
| Empty | QuickJob | 100 | 5 | 1 | 10 | 1234567890 | 0.0000 ns | 0.0000 ns | 0.0000 ns | 0.0000 ns |
| InsertStr | ShortRun | 1 | 3 | 16 | 10 | 1234567890 | 277.5542 ns | 142.1498 ns | 7.7917 ns | 275.7582 ns |
| InitStr | ShortRun | 1 | 3 | 16 | 10 | 1234567890 | 240.7382 ns | 217.4022 ns | 11.9165 ns | 236.3251 ns |
| InsertStringBuilder | ShortRun | 1 | 3 | 16 | 10 | 1234567890 | 354.2914 ns | 182.9307 ns | 10.0270 ns | 359.9009 ns |
| InitStringBuilder | ShortRun | 1 | 3 | 16 | 10 | 1234567890 | 291.1609 ns | 253.5002 ns | 13.8952 ns | 285.7806 ns |
| InsertStringBuilderWithCapacity | ShortRun | 1 | 3 | 16 | 10 | 1234567890 | 339.9996 ns | 35.9658 ns | 1.9714 ns | 340.9990 ns |
| InitStringBuilderWithCapacity | ShortRun | 1 | 3 | 16 | 10 | 1234567890 | 293.8455 ns | 112.6605 ns | 6.1753 ns | 291.8657 ns |
| Empty | ShortRun | 1 | 3 | 16 | 10 | 1234567890 | 0.0013 ns | 0.0216 ns | 0.0012 ns | 0.0015 ns |
код бенчмарка | |
| |