Как проверить, какой метод работает быстрее? - PullRequest
3 голосов
/ 21 июля 2010

В то время как вопрос проверить, является ли ввод тип строки , был закрыт, два из ответов вызвали у меня вопрос микрооптимизации: какое из следующих двух решений будет работать лучше?

Рид Копси предоставил решение с использованием Char.IsLetter:

string myString = "RandomStringOfLetters";
bool allLetters = myString.All( c => Char.IsLetter(c) );

Адаптированное решение с использованием регулярных выражений из Марк Байерс :

string s = "RandomStringOfLetters";
bool allLetters = Regex.IsMatch(s, "^[a-z]+$", RegexOptions.IgnoreCase);

Не желая просто задавать вопрос Риду или Марку, я решил написать быстрый тест, чтобы определить, какие из них лучше.Проблема в том, что я не много занимался оптимизацией кода (я склонен ставить читабельность кода превыше всего).

Кроме того, что нужно делать отметку времени до и после выполнения каждого, что еще есть (лучше?) варианты определения, какое решение работает быстрее?

Редактировать

Я изменил Ответ Мартина для работы с Console.WriteLine(...) и запустил его как консольприложение.Не уверен, как именно LinqPad запускает приложения, но результаты были примерно одинаковыми:

41
178

Ответы [ 6 ]

7 голосов
/ 21 июля 2010

Вы захотите сделать это, измеряя время выполнения с помощью Секундомер .Кроме того, при профилировании следует помнить несколько очень важных вещей:

  1. Всегда выполняйте тест более одного раза.В первый раз, когда вы запустите его, из JIT будут накладные расходы, и время может ввести в заблуждение.Хороший подход - многократный запуск и взятие среднего значения (например, я часто запускаю такой тест 100 000 раз).
  2. Всегда запускайте свой тест с полной версией сборки вне хостинга Visual Studioпроцесс.(По умолчанию вы можете использовать для этого Ctrl + F5.) Хост Visual Studio значительно влияет на время.
2 голосов
/ 21 июля 2010

Я просто собрал это вместе в LINQPad в качестве примера того, как я это сделаю (отсюда вызовы Dump () - замените на Console.WriteLine (...), если вы не используя этот удобный инструмент).

Похоже, что путь LINQ чуть более чем в четыре раза быстрее:

System.Diagnostics.Stopwatch stopwatch = new Stopwatch();

stopwatch.Start();
for (int i = 0; i < 100000; i++)
{
 string myString = "RandomStringOfLetters";
 bool allLetters = myString.All( c => Char.IsLetter(c) );
}
stopwatch.Stop();
stopwatch.ElapsedMilliseconds.Dump();

stopwatch.Reset();

stopwatch.Start();
for (int i = 0; i < 100000; i++)
{
 string s = "RandomStringOfLetters";
 bool allLetters = Regex.IsMatch(s, "^[a-z]+$", RegexOptions.IgnoreCase);
}
stopwatch.Stop();
stopwatch.ElapsedMilliseconds.Dump();

Выход:

47 
196
2 голосов
/ 21 июля 2010

Вы должны проверить System.Diagnostics.Stopwatch!

http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx

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

Надеюсь, это поможет.

0 голосов
/ 21 июля 2010

Шаги, чтобы определить, какой из них быстрее: -

  1. Получить коллекцию компьютеров, которую должны сделать пара сотен, AMD / Intel / другие, 32-разрядные / 64-разрядные,...

  2. Установите каждый .NET Framework, который вам нужен, на каждом из них (по очереди)

  3. Попробуйте каждую комбинацию параметров оптимизации длякомпиляция (в свою очередь)

  4. Используйте StopWatch для проверки большого прогона для каждого

  5. Контролируйте использование памяти для каждого, поскольку это может оказать большее влияниена остальной части вашего приложения.Экономия нескольких циклов за счет увеличения потребления памяти и большего количества операций по сбору мусора часто является плохой «оптимизацией».

Что может дать вам некоторое представление о том, какиебыстрее на практике, по крайней мере, для текущих выпусков компилятора.Повторите с каждым новым выпуском компилятора.

0 голосов
/ 21 июля 2010

Используйте класс System.Diagnostics.Stopwatch.

Запустите секундомер и выполните несколько тысяч итераций, остановите его и проверьте общее количество прошедших миллисекунд

0 голосов
/ 21 июля 2010

Существует класс System.Diagnostics.Stopwatch, который можно использовать.

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

...