Категории
ТОП за месяц
onlinekniga.com » Компьютеры и Интернет » Программирование » Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре

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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 63 64 65 66 67 68 69 70 71 ... 206
Перейти на страницу:

 }

} //конец класса 

Повторно используйте размещенные в памяти объекты при любом удобном случае

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

Листинг 8.5. Тестовый пример, демонстрирующий уменьшение объема памяти, распределяемой для объектов (типичный образец улучшения первоначального варианта реализации интересующей нас функции) 

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

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

 //Вызвать сборщик мусора, чтобы тест

 //начинался с чистого состояния.

 //ПРИБЕГАЙТЕ К ЭТОЙ МЕРЕ ТОЛЬКО В ЦЕЛЯХ ТЕСТИРОВАНИЯ! Вызовы

 //сборщика мусора в программах вручную будут приводить к снижению

 //общей производительности приложений!

 System.GC.Collect();

 string[] testArray = null;

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

 //Просмотреть элементы массива и найти

 //те из них, в которых средним словом является

 //"blue". Заменить "blue" на "orange"

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

 //Запустить секундомер!

 PerformanceSampling.StartSample(1, "LessWasteful");

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

 //БОЛЕЕ ЭКОНОМНЫЙ СПОСОБ: Распределить память

 //для объекта до вхождения в цикл

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

 LessWastefulWorkerClass workerClass1;

 workerClass1 = new LessWastefulWorkerClass();

 int outerLoop;

 for (outerLoop = 0; outerLoop < LOOP_SIZE; outerLoop++) {

  //Присвоить элементам массива значения, которые

  //мы хотим использовать при тестировании

  ResetTestArray(ref testArray);

  int topIndex = testArray.Length - 1;

  for(int idx = 0; idx <= topIndex; idx++) {

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

   //Теперь вместо повторного распределения памяти для объекта

   //нам достаточно лишь повторно воспользоваться им

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

   //workerClass1 = new WastefulWorkerClass(

   // testArray[topIndex]);

   workerClass1.ReuseClass(testArray[idx]);

   //Если средним словом является "blue", заменить его на "orange"

   if (workerClass1.MiddleSegment == "blue") {

    //Заменить средний сегмент

    workerClass1.MiddleSegment = "orange";

    //Заменить слово

    testArray[idx] = workerClass1.getWholeString();

   }

  }

 }

 //Остановить секундомер!

 PerformanceSampling.StopSample(1);

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

}

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

using System;

public class LessWastefulWorkerClass {

 private string m_beginning_segment;

 public string BeginSegment {

  get { return m beginning_segment; }

  set { m_beginning_segment = value; }

 }

 private string m_middle_segment;

 public string MiddleSegment {

  get { return m_middle_segment; }

  set { m_middle segment = value; }

 }

 private string m_end_segment;

 public string EndSegment {

  get { return m_end_segment; }

  set { m_end_segment = value; }

 }

 public void ReuseClass(string in word) {

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

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

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

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

  m_beginning_segment = "";

  m_middle_segment = "";

  m_end_segment = "";

  int index_segment1;

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

  index segment1 = in_word.IndexOf(" ",0);

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

  if (index_segment1 == -1) {

   m_beginning_segment = in_word;

   return;

  }

  //Если присутствует символ " ", усечь его

  else {

   if (index_segment1 == 0) {

  } else {

    m_beginning_segment = in_word.Substring(0, index_segment1);

   }

   int index_segment2;

   index_segment2 = in_word.IndexOf("_", index_segment1 + 1);

   if (index_segment2 == -1) {

    m_end_segment = in_word.Substring(index_segment1 + 1);

    return;

   }

   //Установить последний сегмент

   m_middle_segment = in_word.Substring(index_segment1 + 1, index_segment2 - index_segment1 - 1);

   m_end_segment = in_word.Substring(index_segment2 + 1);

  }

 }

 public string getWholeString() {

  return m_beginning_segment + "_" + m_middle_segment + "_" + m_end_segment;

 }

}

Предшествующий код оставляет возможности для внесения дальнейших улучшений

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

Избегайте размещения в памяти лишних объектов

Обратите внимание на то, что в приведенном выше коде мы часто вычисляем множество величин, которые нам не нужны. В частности, мы генерируем в каждой итерации цикла, по крайней мере, три новых строки: одну для первого сегмента, одну для среднего сегмента и одну для конечного сегмента исходной строки. Например, строка big_blue_boat разбивается на три различных строки: big, blue и boat. Для создания этих строк требуется определенное время, а, кроме того, впоследствии мы должны освободить занимаемую ими память.

В алгоритме выполняется проверка только среднего сегмента, в ходе которой устанавливается, совпадает ли он с некоторым конкретным значением (blue). Если совпадения нет. дальнейшая обработка не требуется. Это означает, что большую часть времени мы напрасно распределяем память для строк, предназначенных для размещения среднего и конечного сегментов, даже если они используются алгоритмом всего лишь для того, чтобы вновь собрать целую строку из отдельных кусочков. Что если вместо создания целых строк из кусочков старой строки в каждой итерации цикла мы будем просто сохранять символьные индексные значения, которые указывают нам, где находятся символы подчеркивания (_) в строке? Мы можем сохранять эти данные в виде целых чисел, накладные расходы для которых должны быть значительно меньше, чем при размещении новых строк. Если мы поступим именно таким образом, то сможем использовать исходные строковые и индексные значения для сравнения строк, начиная с первого символа подчеркивания и доходя до второго символа подчеркивания (например, blue_). Лишь в тех случаях, когда обнаруживается совпадение, нам потребуется создавать дополнительную строку для замены среднего сегмента. В большинстве случаев ситуация для нас намного улучшится и нам не надо будет распределять память для каких-либо объектов или строк. Лишь в тех случаях, когда обнаруживается совпадение средних сегментов, нам потребуется выполнять дополнительные строковые операции, но в любом случае нам придется выполнить не больше операций, чем выполнялось ранее. Как бы то ни было, хуже не будет.

Листинг 8.7. Тестовый пример, демонстрирующий значительное уменьшение объема памяти, распределяемой для объектов (типичный образец существенной алгоритмической оптимизации первоначального варианта реализации интересующей нас функции) 

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

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

 //Вызвать сборщик мусора, чтобы тест //начинался с чистого состояния.

 //ПРИБЕГАЙТЕ К ЭТОЙ МЕРЕ ТОЛЬКО В ЦЕЛЯХ ТЕСТИРОВАНИЯ! Вызовы

 //сборщика мусора в программах вручную будут приводить к снижению

 //общей производительности приложений!

 System.GC.Collect();

 string[] testArray = null;

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

 //Просмотреть элементы массива и найти

 //те из них, в которых средним словом является

 //"blue". Заменить "blue" на "orange"

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

 //Запустить секундомер перед началом выполнения теста

1 ... 63 64 65 66 67 68 69 70 71 ... 206
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре.
Комментарии