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

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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

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

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

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

 }

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

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

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