Время, прошедшее между двумя функциями

Мне нужно найти время, прошедшее между двумя функциями, выполняющими одну и ту же операцию, но написанными по другому алгоритму. Мне нужно найти самую быструю среди двух

Вот мой фрагмент кода

Stopwatch sw = new Stopwatch();
sw.Start();
Console.WriteLine(sample.palindrome()); // algorithm 1
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);//tried sw.elapsed and sw.elapsedticks
sw.Reset(); //tried with and without reset
sw.Start();
Console.WriteLine(sample.isPalindrome()); //algorithm 2
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

Технически это должно дать время, затраченное на два алгоритма. Это дает алгоритм 2 быстрее. Но он дает разное время, если я меняю вызов двух функций. Например, если я сначала вызову алгоритм2 и алгоритм1, он говорит, что алгоритм1 быстрее.

Я не знаю, что я делаю неправильно.

Ответы

Ответ 1

Я предполагаю, что ваши методы палиндрома работают в очень быстро в этом примере, и поэтому для получения реального результата вам нужно будет запустить их пару раз, а затем решить, что быстрее.
Что-то вроде этого:

int numberOfIterations = 1000; // you decide on a reasonable threshold.
sample.palindrome(); // Call this the first time and avoid measuring the JIT compile time
Stopwatch sw = new Stopwatch();
sw.Start();
for(int i = 0 ; i < numberOfIterations ; i++)
{
   sample.palindrome(); // why console write?
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); // or sw.ElapsedMilliseconds/numberOfIterations 

Теперь сделайте то же самое для второго метода, и вы получите более реалистичные результаты.

Ответ 2

Вам нужно выполнить оба метода до того, как фактические расчетные тесты для скомпилированного кода будут JIT'd. Затем проверьте несколько попыток. Вот макет кода.

Скомпилированный код в формате CIL будет JIT'd при первом выполнении, он будет переведен в машинный код. Поэтому сначала тестирование на нем является точным. Так что пусть код будет JIT'd, прежде чем тестировать его.

sample.palindrome();
sample.isPalindrome();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 1000; i++)
{
    sample.palindrome();
    Console.WriteLine("palindrome test #{0} result: {1}", i, sw.ElapsedMilliseconds);
}
sw.Stop();
Console.WriteLine("palindrome test Final result: {0}", sw.ElapsedMilliseconds);
sw.Restart();
for (int i = 0; i < 1000; i++)
{
    sample.isPalindrome();
    Console.WriteLine("isPalindrome test #{0} result: {1}", i, sw.ElapsedMilliseconds);
}
sw.Stop();
Console.WriteLine("isPalindrome test Final result: {0}", sw.ElapsedMilliseconds);

Подробнее о CIL и JIT

Ответ 3

Если вы не предоставите код функции палиндрома и isPalindrome вместе с классом образцов, я не могу сделать ничего, кроме предположения.

Наиболее вероятная причина, по которой я полагаю, заключается в том, что обе ваши функции используют одни и те же переменные класса и другие данные. Поэтому, когда вы вызываете функцию в первый раз, она должна выделять память для переменных, тогда как в следующий раз, когда вы вызываете какую-то другую функцию, эти одноразовые расходы уже произошли. Если не переменные, это может быть другое дело, но по тем же направлениям.

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

Сообщите мне, если это сработает. Это просто размышления с моей стороны, и я могу ошибаться.