Чтение онлайн

на главную

Жанры

Программирование мобильных устройств на платформе .NET Compact Framework

Салмре Иво

Шрифт:

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

Получение информации об основных показателях производительности в .NET Compact Framework

В .NET Compact Framework версии 1.1 имеется встроенный механизм, позволяющий быстро получать "черновую" метрику работы приложений на основе управляемого кода в этой среде. Упомянутый механизм обеспечивает получение показателей производительности приложения в целом и по завершении выполнения приложения выводит соответствующий текстовый файл. В этом текстовом файле содержатся следующие данные:

• Суммарное время выполнения

• Количество объектов, размещенных в памяти в процессе выполнения кода.

• Количество

операций по сборке мусора, произведенных в процессе выполнения кода.

• Количество сгенерированных исключений. (Накладные расходы, связанные с обработкой исключений, возбуждаемых часто и без крайней на то необходимости внутри циклов, могут оказаться весьма существенными )

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

Технические рекомендации относительно того, как активизировать генерацию рассматриваемых показателей времени выполнения, содержатся в статье "Developing Well Performing .NET Compact Framework Applications" ("Разработка высокопроизводительных приложений .NET Compact Framework") на Web-сайте http://msdn.microsoft.com.

На момент написания данной книги указанная статья располагалась по следующему 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 секунды), чем указанное. Вам придется немного поэкспериментировать самостоятельно. Если окажется, что вам необходим счетчик с более высоким разрешением, можете видоизменить приведенный выше код, включив в него системные вызовы операционной системы, управляющей собственным кодом, для получения доступа к низкоуровневым системным счетчикам. В большинстве случае возможностей приведенного выше кода вам должно быть вполне достаточно, а в силу своей простоты он оказывается удобным для использования в тех случаях, когда измерения требуется выполнить быстро.

Листинг 7.2. Тестовая программа, демонстрирующая использование приведенного выше кода для измерения временных интервалов

private void button1_Click(object sender, System.EventArgs e) {

 const int TEST_SAMPLE_INDEX = 2; //Выберите любое действительное

//значение индекса

 //Начать измерение

 PerformanceSampling.StartSample(TEST_SAMPLE_INDEX, "TestSample");

 //Отобразить окно сообщений

 System.Windows.Forms.MessageBox.Show("Для прекращения измерения щелкните на кнопке OK");

 //Прекратить измерение

 PerformanceSampling.StopSample(TEST_SAMPLE_INDEX);

 //Отобразить результаты

 System.Windows.Forms.MessageBox.Show(PerformanceSampling.GetSampleDurationText(TEST_SAMPLE_INDEX));

}

Советы относительно повышения надежности результатов измерений

1. Вы можете пользоваться эмпирическим правилом, в соответствии с которым чем больше длительность события, которую вы измеряете, тем меньше относительная ошибка. Поэтому, если вы сравниваете два алгоритма, для выполнения которых требуется примерно 0,5 секунды, лучше выполнить каждый из них по 10 раз и разделить полученные результаты на 10.

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

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

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

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

Поделиться:
Популярные книги

Ретроградный меркурий

Рам Янка
4. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ретроградный меркурий

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон

Полковник Империи

Ланцов Михаил Алексеевич
3. Безумный Макс
Фантастика:
альтернативная история
6.58
рейтинг книги
Полковник Империи

Бремя империи

Афанасьев Александр
Бремя империи - 1.
Фантастика:
альтернативная история
9.34
рейтинг книги
Бремя империи

Инферно

Кретов Владимир Владимирович
2. Легенда
Фантастика:
фэнтези
8.57
рейтинг книги
Инферно

Адмирал южных морей

Каменистый Артем
4. Девятый
Фантастика:
фэнтези
8.96
рейтинг книги
Адмирал южных морей

Защитник

Астахов Евгений Евгеньевич
7. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Защитник

Я – Орк. Том 3

Лисицин Евгений
3. Я — Орк
Фантастика:
юмористическое фэнтези
попаданцы
5.00
рейтинг книги
Я – Орк. Том 3

Мир-о-творец

Ланцов Михаил Алексеевич
8. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Мир-о-творец

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Я – Орк. Том 4

Лисицин Евгений
4. Я — Орк
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 4

Хозяйка лавандовой долины

Скор Элен
2. Хозяйка своей судьбы
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Хозяйка лавандовой долины

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9