При сравнительном тестировании маленьких примеров кода в C# может быть улучшена эта реализация?

Это правильный ответ:

ALTER TABLE MEN DROP COLUMN Lname

Но ... если CONSTRAINT существует на COLUMN, то сначала вы должны DROP CONSTRAINT, тогда вы будете способный DROP к COLUMN. Чтобы сбросить CONSTRAINT, запустите:

ALTER TABLE MEN DROP CONSTRAINT {constraint_name_on_column_Lname}
104
задан Artemix 21 May 2013 в 15:33
поделиться

7 ответов

Вот измененная функция: как рекомендовано сообществом, не стесняйтесь вносить поправки в это вики сообщества.

static double Profile(string description, int iterations, Action func) {
    //Run at highest priority to minimize fluctuations caused by other processes/threads
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
    Thread.CurrentThread.Priority = ThreadPriority.Highest;

    // warm up 
    func();

    var watch = new Stopwatch(); 

    // clean up
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();

    watch.Start();
    for (int i = 0; i < iterations; i++) {
        func();
    }
    watch.Stop();
    Console.Write(description);
    Console.WriteLine(" Time Elapsed {0} ms", watch.Elapsed.TotalMilliseconds);
    return watch.Elapsed.TotalMilliseconds;
}

Убедитесь, что вы компилируете в Release с включенной оптимизацией, и запускаете тесты вне Visual Studio . Эта последняя часть важна, потому что JIT ограничивает свою оптимизацию подключенным отладчиком даже в режиме Release.

93
ответ дан 24 November 2019 в 04:11
поделиться

Если вы хотите исключить из уравнения взаимодействия с GC, вы можете запустить свой «разогревающий» вызов после вызова GC.Collect, а не до него. Таким образом, вы знаете, что .NET уже имеет достаточно памяти, выделенной из ОС для рабочего набора вашей функции.

Имейте в виду, что вы выполняете вызов метода без встроенного кода для каждой итерации, поэтому убедитесь, что вы сравниваете вещи, которые вы тестируете, на пустое тело. Вам также придется признать, что вы можете надежно рассчитать время только для тех вещей, которые в несколько раз длиннее, чем вызов метода.

Кроме того, в зависимости от того, какие данные вы профилируете,

15
ответ дан 24 November 2019 в 04:11
поделиться

Завершение не обязательно будет завершено до возврата GC.Collect . Завершение ставится в очередь, а затем выполняется в отдельном потоке. Этот поток все еще может быть активен во время ваших тестов, что повлияет на результаты.

Если вы хотите убедиться, что финализация завершена перед запуском тестов, вы можете вызвать GC.WaitForPendingFinalizers , который будет блокироваться до тех пор, пока очередь завершения очищена:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
22
ответ дан 24 November 2019 в 04:11
поделиться

Я бы вообще избегал передачи делегата:

  1. Вызов делегата - это вызов виртуального метода. Недешево: ~ 25% наименьшего объема памяти, выделенного в .NET. Если вас интересуют подробности, см. , например, по этой ссылке .
  2. Анонимные делегаты могут привести к использованию замыканий, которые вы даже не заметите. Опять же, доступ к полям закрытия заметно отличается, например, от доступа к переменной в стеке.

Пример кода, приводящего к использованию закрытия:

public void Test()
{
  int someNumber = 1;
  Profiler.Profile("Closure access", 1000000, 
    () => someNumber + someNumber);
}

Если вы не знаете о замыканиях, взгляните на этот метод в .NET Reflector.

6
ответ дан 24 November 2019 в 04:11
поделиться

I think the most difficult problem to overcome with benchmarking methods like this is accounting for edge cases and the unexpected. For example - "How do the two code snippets work under high CPU load/network usage/disk thrashing/etc." They're great for basic logic checks to see if a particular algorithm works significantly faster than another. But to properly test most code performance you'd have to create a test that measures the specific bottlenecks of that particular code.

I'd still say that testing small blocks of code often has little return on investment and can encourage using overly complex code instead of simple maintainable code. Writing clear code that other developers, or myself 6 months down the line, can understand quickly will have more performance benefits than highly optimized code.

6
ответ дан 24 November 2019 в 04:11
поделиться

Вы также должны выполнить "прогрев" перед фактическим измерением, чтобы исключить время, которое JIT-компилятор тратит на подгонку вашего кода.

1
ответ дан 24 November 2019 в 04:11
поделиться

Я бы вызвал func () несколько раз для разминки, а не только один.

5
ответ дан 24 November 2019 в 04:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: