На момент написания данной книги указанная статья располагалась по следующему URL-адресу:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/netcfperf.asp
Кроме того, в этой статье рассматриваются различные способы оценки функциональности кода на основании сравнительного анализа показателей производительности; этот материал также заслуживает прочтения.
Программа для измерения характеристик кода
Поскольку проектирование высокопроизводительных приложений — это искусство, которое должно сочетаться с исследовательским подходом, полезно иметь под рукой инструмент, с помощью которого можно было бы быстро производить необходимые измерения. Приведенный ниже пример кода вы можете использовать в своих программах для количественной оценки некоторых показателей их функционирования.
Представленный в листинге 7.1 код прост в использовании и имеет небольшие размеры, благодаря чему его включение в мобильное приложение приведет лишь к незначительному увеличению накладных расходов. Этот код предназначен для использования в качестве универсального средства тестирования производительности, при помощи которого вы сможете быстро измерять временные характеристики своих кодов. Это позволит вам быстро оценивать, сколько времени выполняется тот или иной участок разрабатываемого кода, и обнаруживать узкие места, требующие применения новых стратегий. Вы также можете использовать этот код для быстрого сравнения эффективности двух различных подходов, чтобы определить, какой из них лучше соответствует вашим запросам. Так, если для если для настройки пользовательского интерфейса и заполнения иерархического списка в элементе управления TreeView требуется три секунды, то вы можете захотеть изменить алгоритм таким образом, чтобы сначала заполнялись лишь узлы наивысшего уровня, а заполнение дочерних узлов откладывалось на более позднее время и осуществлялось лишь тогда, когда в этом возникнет действительная необходимость. Окончательное решение вы будете принимать на основании результатов соответствующих измерений и оценок качества приложения, предоставляемых конечными пользователями.
Листинг 7.1. Пример кода для измерения временных интервалов, который вы можете использовать для хронометража работы своих приложений
using System;
internal class PerformanceSampling {
//Значение этого параметра может быть задано произвольным, но количество
//тестовых интервалов, равное 8, представляется достаточным для
// большинства случаев
const int NUMBER_SAMPLERS = 8;
static string[] m_perfSamplesNames = new string[NUMBER_SAMPLERS];
static int[] m_perfSamplesStartTicks = new int[NUMBER_SAMPLERS];
static int[] m_perfSamplesDuration = new int[NUMBER_SAMPLERS];
//Определить начальное значение счетчика тактов системных часов
//для интервала
internal static void StartSample(int sampleIndex, string sampleName) {
m_perfSamplesNames[sampleIndex] = sampleName;
m_perfSamplesStartTicks[sampleIndex] = System.Environment.TickCount;
}
//Определить конечное значение счетчика тактов системных часов
//для интервала
internal static void StopSample(int sampleIndex) {
int stopTickCount = System.Environment.TickCount;
//Счетчик тактов системных часов сбрасывается в ноль каждые 24,9 дня
//(что соответствует примерно 2 миллиардам миллисекунд).
//Эта маловероятная возможность будет принята нами во внимание
if (stopTickCount >=m_perfSamplesStartTicks[sampleIndex]) {
//Обычно будет выполняться этот код
m_perfSamplesDuration[sampleIndex] = stopTickCount - m_perfSamplesStartTicks[sampleIndex];
} else {
//Значение счетчика тактов "перешло" через ноль,
//и мы должны это учесть
m_perfSamplesDuration[sampleIndex] = stopTickCount + (int.MaxValue - m_perfSamplesStartTicks[sampleIndex]) + 1;
}
}
//Возвратить длительность тестового интервала
//(в миллисекундах)
internal static int GetSampleDuration(int sampleIndex) {
return m_perfSamplesDuration[sampleIndex];
}
//Возвращает длительность истекшего тестового
//интервала в секундах
internal static string GetSampleDurationText(int sampleIndex) {
return m_perfSamplesNames[sampleIndex] + ": " +
System.Convert.ToString((m_perfSamplesDuration[sampleIndex] /(double) 1000.0)) +
" секунд.";
}
}
HA ЗАМЕТКУ
В документации по .NET Compact Framework утверждается, что интервал значений свойства .TickCount не может быть меньше 500 мс (0,5 секунды). Я обнаружил, что на практике достигается несколько лучшее разрешение (менее 100 мс, или 0,1 секунды), чем указанное. Вам придется немного поэкспериментировать самостоятельно. Если окажется, что вам необходим счетчик с более высоким разрешением, можете видоизменить приведенный выше код, включив в него системные вызовы операционной системы, управляющей собственным кодом, для получения доступа к низкоуровневым системным счетчикам. В большинстве случае возможностей приведенного выше кода вам должно быть вполне достаточно, а в силу своей простоты он оказывается удобным для использования в тех случаях, когда измерения требуется выполнить быстро.
Читать дальше