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

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