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

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Иво Салмре, "Программирование мобильных устройств на платформе .NET Compact Framework" бесплатно, без регистрации.
Перейти на страницу:

Во многих случаях, если вы хотите инкапсулировать некоторые простые данные, то для локальных переменных внутри функций гораздо эффективнее использовать не объекты, а структуры. Структура — это просто удобный способ сгруппировать в одном пакете взаимосвязанные данные, а не передавать их в виде отдельных переменных.

Структуры обладают более простыми свойствами по сравнению с объектами, но могут "упаковываться" в объекты и передаваться внутри программы так же, как они, если в этом возникает необходимость. Использование структур предоставляет определенные удобства и может привести к некоторому увеличению производительности (по сравнению с вариантом, когда используются объекты), но поскольку они выглядят, а во многих случаях и действуют подобно объектам и могут заключаться в объекты-оболочки, необходимо тщательно взвешивать, когда их следует использовать, чтобы избежать дополнительных накладных расходов и не создать лишнего мусора. В сомнительных случаях тестируйте алгоритмы, используя как отдельные переменные (например, базовые типы, подобные int, string, double), так и структуры, чтобы сравнить производительность приложения в обоих случаях и убедиться в том, что она остается примерно одинаковой.

Более подробную информацию по этому вопросу вы можете получить, обратившись к разделам справочной документации .NET Compact Framework, посвященным типам значений ("value types") и структурам ("struct"). Ниже приводится пример с объявлениями структуры и класса:

//Примечание. В VB.NET это был бы тип (type), а не структура (struct)

//Это структура

struct MyRect_Type {

 public int x;

 public int у;

}

//Это класс

class MyRect_Class {

 public int x;

 public int у;

}

//Код примера

class TestClass {

 public void foo() {

 //Требуется распределять как объект

 MyRect_Class myRectClass = new MyRect_Class();

 myRectClass.x = 1;

 myRectClass.y = 2;

 //Этот оператор распределяет новый объект

 myRectClass = new MyRect_Class();

 //Можно объявить как скалярный тип

 MyRect_Type myRectType;

 myRectType.x = 1;

 myRectType.y = 2;

 //Этот оператор обнуляет значения в структуре, но не

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

 myRectType = new MyRect_Type();

}

Пишите экономные алгоритмы: разумно расходуйте память и повторно используйте объекты

Представленный ниже пример иллюстрирует несколько различных вариантов реализации одного и того же базового алгоритма. Алгоритм предназначен для обработки массива строк. Каждая строка в массиве состоит из трех частей, разделенных символом подчеркивания (например, big_shaggy_dog). Алгоритм предполагает просмотр каждого из элементов массива и проверку того, не является ли его средняя часть словом blue (например, my_blue_car). Если это так, то слово blue заменяется словом orange (например, my_blue_car становится my_orange_car).

Кроме того, в каждом из описанных алгоритмов используется вспомогательный класс, упрощающий разбиение строк и получение данных, содержащихся в каждом из трех сегментов. Первый алгоритм (листинги 8.3 и 8.4) представляет собой некое разумное первое приближение, а следующие два алгоритма (листинги 8.5 и 8.6 и листинги 8.7 и 8.8) — его оптимизированные варианты, улучшающие первоначальную тактику. Целью оптимизации являлось непосредственное улучшение производительности, а также уменьшение количества "мусора", вырабатываемого каждым из алгоритмов.

Листинг 8.2. Общий код, используемый во всех приведенных ниже вариантах тестов

//Желаемое число повторений теста

const int LOOP_SIZE = 8000;

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

//Эта функция переустанавливает содержимое нашего тестового

//массива, что обеспечивает возможность многократного

//выполнения тестового алгоритма

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

private void ResetTestArray(ref string[] testArray) {

 if (testArray == null) {

  testArray =new string[6];

 }

 testArray[0] = "big_blue_duck";

 testArray[1] = "small_yellow_horse";

 testArray[2] = "wide_blue_cow";

 testArray[3] = "tall_green_zepplin";

 testArray[4] = "short_blue_train";

 testArray[5] = "short_purple_dinosaur";

}

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

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

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

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

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

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

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

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

 System.GC.Collect();

 string [] testArray = null;

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

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

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

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

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


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

 PerformanceSampling.StartSample(0, "WastefulWorkerClass");

 WastefulWorkerClass workerClass1;

 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[idx]);

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

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

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

    workerClass1.MiddleSegment = "orange";

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

    testArray[idx] = workerClass1.getWholeString();

   }

  } //конец внутреннего цикла for

 }//конец внешнего цикла for

 //Получить время окончания теста

 PerformanceSampling.StopSample(0);

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

}

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

using System;

public class WastefulWorkerClass {

 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 WastefulWorkexClass(string in_word) {

  int index_segment1;

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

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

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

  if (index_segment1 == -1) {

   m_beginning_segment = in_word;

   m_middle_segment = "";

   m_end_segment = "";

   return;

  }

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

  else {

   //Если первым символом является "_", то первым сегментом будет ""

   if (index_segment1 == 0) {

   m_beginning_segment = "";

  } 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_middle_segment = "";

   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;

 }

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

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

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*