Выбрать главу

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

}

Листинг 8.8. Рабочий класс для третьего тестового примера

using System;

public class LessAllocationsWorkerClass {

 public string MiddleSegment {

  set { m_middleSegmentNew= value; }

 }

 private string m_middleSegmentNew;

 private int m_index_1st_undscore;

 private int m_index_2nd undscore;

 private string m_stringIn;

 public void ReuseClass(string in_word) {

  //----------------------------------------------

  //Для повторного использования класса необходимо

  //полностью очистить внутреннее состояние

  //----------------------------------------------

  m_index_1st_undscore = -1;

  m_index_2nd_undscore = -1;

  m_middleSegmentNew= null;

  m_stringIn = in_word; //Это не приводит к созданию копии строки

  //Осуществляем поиск символов подчеркивания ("_") в строке

  m_index_1st_undscore = in_word.IndexOf("_",0);

  //B случае отсутствия символов "_" все, что нам нужно, это первый сегмент

  if (m_index_1st_undscore == -1) {

   return;

  }

  //Найти второй символ " "

  m_index 2nd_undscore = in_word.IndexOf(" ", m_index_1st_undscore + 1);

 }

 public int CompareMiddleSegment(string compareTo) {

  //B случае отсутствия второго символа "_" отсутствует и средний сегмент

  if (m_index_2nd_undscore < 0) {

   //Если мы сравниваем с пустой строкой,

   //то это означает совпадение

   if((compareTo == null) || (compareTo == "")) {return 0;}

   return -1;

  }

  //Сравнить средний сегмент с первым и вторым сегментами

  return System.String.Compare(

   m_stringIn, m_index_1st_undscore + 1, compareTo, 0, m_index_2nd_undscore - m_index_1st_undscore -1);

 }

 public string getWholeString() {

  //Если полученный средний сегмент не является новым,

  //возвратить исходный сегмент

  if (m_middleSegmentNew == null) {

   return m_stringIn;

  }

  //Создать возвращаемую строку

  return m_stringIn.Substring(0, m_index_1st_undscore + 1) +

   m_middleSegmentNew +

   m_stringIn.Substring(m_index_2nd_undscore, m_stringIn.Length - m_index_2nd_undscore);

 }

}

Анализ описанных выше шагов последовательной оптимизации

Обычно в тонкой настройке алгоритмов таятся значительные резервы. Самое важное при этом — это контролировать, обеспечивает ли выполнение настройки выигрыш в производительности, на который вы рассчитывали. Некоторыми своими "усовершенствованиями" вы можете непреднамеренно ухудшить производительность из-за того, что с ними связано распределение памяти, о котором вы можете не знать, или в силу каких-либо других причин. В процессе разработки приведенного выше кода у меня несколько раз возникали ситуации, когда я считал, что вносимые изменения должны улучшить результаты, но после проведения соответствующих измерений и при более глубоком рассмотрении оказывалось, что эти изменения приносили только вред. Всегда измеряйте показатели производительности и проводите их сравнительный анализ для различных вариантов реализации!

Кроме того, очень важно проводить тестирование на фактическом оборудовании, для которого предназначено ваше приложение, чтобы лучше почувствовать реальные условия работы с ним "на устройстве". Эмуляторы очень удобно использовать в процессе проектирования и базовой настройки приложения, но результаты, полученные на физическом устройстве, могут быть другими из-за различий в свойствах процессоров, памяти и других факторов. Одни программы могут выполняться на физических устройствах быстрее, другие — медленнее. Последнее слово всегда остается за фактическим оборудованием, которое будут использовать конечные пользователи. По тем же причинам очень важно измерять производительность при выполнении программы с подключенным отладчиком и без него. В некоторых случаях подключение отладчика резко снижает производительность.

Результаты тестирования трех различных алгоритмов, обсуждаемых нами, представлены в таблицах 8.1 и 8.2.

Таблица 8.1. Результаты тестирования алгоритмов (в секундах) на эмуляторе Pocket PC с вычислением 8000 циклов

Порядковый номер теста Неэкономное распределение памяти Незначительное уменьшение объема распределяемой памяти Значительное уменьшение объема распределяемой памяти 1 12,65 12,2 8,925 2 12,775 12,35 8,55 3 12,575 12,25 8,225 4 12,625 12,525 8,575 Среднее 12,65625 12,33125 8,56875 Экономия времени по сравнению с базовым уровнем 0% 2,57% 32,30%

Таблица 8.2. Результаты тестирования алгоритмов (в секундах) на физическом устройстве Pocket PC с вычислением 2000 циклов

Порядковый номер теста Неэкономное распределение памяти Незначительное уменьшение объема распределяемой памяти Значительное уменьшение объема распределяемой памяти 1 30,609 30,151 20,484 2 30,538 30,016 20,362 3 30,517 30,195 20,377 4 30,457 30,316 20,429 Среднее 30,53025 30,1695 20,413 Экономия времени по сравнению с базовым уровнем 0% 1,18% 33,14%