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

Листинг 11.1. Заполнение данными и очистка от них элементов управления TreeView с использованием альтернативных стратегий

Листинг 11.1. Заполнение данными и очистка от них элементов управления TreeView с использованием альтернативных стратегий

//---------------------------------------------------------------------
//Примечание #1: В этом примере используется класс PerformanceSampling,
// определенный ранее в данной книге. Убедитесь в том, что
// вы включили этот класс в свой проект.
//Примечание #2: Этот код необходимо включить в класс Form, содержащий
// элемент управления TreeView и кнопки Button, к которым
// подключены приведенные ниже функции xxx_Click.
//---------------------------------------------------------------------
//Количество элементов, которые необходимо поместить в элемент
//управления TreeView
const int NUMBER_ITEMS = 800;
//-------------------------------------------------------------------------
//Код для кнопки "Fill: Baseline"
//
//Использование неоптимизированного подхода для заполнения данными элемента
//управления TreeView
//-------------------------------------------------------------------------
private void UnOptimizedFill_Click(object sender, System.EventArgs e) {
 //Очистить массив для создания одинаковых условий тестирования
 if (treeView1.Nodes.Count > 0) {
  treeView1.BeginUpdate();
  treeView1.Nodes.Clear();
  treeView1.EndUpdate();
  treeView1.Update();
 }
 //Для повышения корректности тестирования предварительно выполнить
 //операцию сборки мусора
 System.GC.Collect();
 //Запустить таймер
 PerformanceSampling.StartSample(0, "TreeViewPopulate");
 //Заполнить данными элемент управления TreeView
 for (int i = 0; i < NUMBER_ITEMS; i++) {
  treeView1.Nodes.Add("TreeItem" + i.ToString());
 }
 //Остановить таймер и отобразить результат
 PerformanceSampling.StopSample(0);
 System.Windows.Forms.MessageBox.Show(PerformanceSampling.GetSampleDurationText(0));
}
//-------------------------------------------------------------------------
//Код для кнопки "Clear: Baseline"
//
//Использование неоптимизированного подхода для заполнения данными элемента
//управления TreeView
//-------------------------------------------------------------------------
private void UnOptimizedClear_Click(object sender, System.EventArgs e) {
 //Для повышения корректности тестирования предварительно выполнить
 //операцию сборки мусора
 System.GC.Collect();
 //Запустить таймер
 PerformanceSampling.StartSample(1, "TreeViewClear");
 treeView1.Nodes.Clear();
 PerformanceSampling.StopSample(1);
 System.Windows.Forms.MessageBox.Show(PerformanceSampling.GetSampleDurationText(1));
}
//--------------------------------------------------
//Код для кнопки "Fill: BeginUpdate"
//
//Подход, в котором используется метод BeginUpdate()
//--------------------------------------------------
private void UseBeginEndUpdateForFill_Click(object sender, System.EventArgs e) {
 //Очистить массив для создания одинаковых условий тестирования
 if (treeViewl.Nodes.Count > 0) {
  treeView1.BeginUpdate();
  treeView1.Nodes.Clear();
  treeView1.EndUpdate();
  treeView1.Update();
 }
 //Для повышения корректности тестирования предварительно выполнить
 //операцию сборки мусора
 System.GC.Collect();
 //Запустить таймер
 PerformanceSampling.StartSample(2, "Populate - Use BeginUpdate");
 //Заполнить данными элемент управления
 TreeView treeView1.BeginUpdate();
 for (int i = 0; i < NUMBER_ITEMS; i++) {
  treeView1.Nodes.Add("TreeItem" + i.ToString());
 }
 treeView1.EndUpdate();
 //Остановить таймер и отобразить результат
 PerformanceSampling.StopSample(2);
 System.Windows.Forms.MessageBox.Show(PerformanceSampling.GetSampleDurationText(2));
}
//--------------------------------------------------
//Код для кнопки "Clear: BeginUpdate"
//Подход, в котором используется метод BeginUpdate()
//--------------------------------------------------
private void UseBeginEndUpdateForClear_Click(object sender, System.EventArgs e) {
 //Для повышения корректности тестирования предварительно выполнить
 //операцию сборки мусора
 System.GC.Collect();
 //Запустить таймер
 PerformanceSampling.StartSample(3, "Clear - Use BeginUpdate");
 treeView1.BeginUpdate();
 treeView1.Nodes.Clear();
 treeView1.EndUpdate();
 //Остановить таймер и отобразить результат
 PerformanceSampling.StopSample(3);
 System.Windows.Forms.MessageBox.Show(PerformanceSampling.GetSampleDurationText(3));
}
//-------------------------------------
//Код для кнопки "Fill: Use Array"
//
//Подход, в котором используется массив
//-------------------------------------
private void FillArrayBeforeAttachingToTree_Click(object sender, System.EventArgs e) {
 //Очистить массив для создания одинаковых условий тестирования
 if (treeView1.Nodes.Count > 0) {
  treeView1.BeginUpdate();
  treeView1.Nodes.Clear();
  treeView1.EndUpdate();
  treeView1.Update();
 }
 //Для повышения корректности тестирования предварительно выполнить
 //операцию сборки мусора
 System.GC.Collect();
 //Запустить таймер
 PerformanceSampling.StartSample(4, "Populate - Use Array");
 //Распределить память для нашего массива узлов дерева
 System.Windows.Forms.TreeNode [] newTreeNodes = new System.Windows.Forms.TreeNode[NUMBER_ITEMS];
 //Заполнить массив
 for(int i = 0; i < NUMBER_ITEMS; i++) {
  newTreeNodes[i] = newSystem.Windows.Forms.TreeNode("TreeItem" + i.ToString());
 }
 //Связать массив с элементом управления
 TreeView treeView1.BeginUpdate();
 treeView1.Nodes.AddRange(newTreeNodes);
 treeView1.EndUpdate();
 //Остановить таймер и отобразить результат
 PerformanceSampling.StopSample(4);
 System.Windows.Forms.MessageBox.Show(PerformanceSampling.GetSampleDurationText(4));
}

Результаты, полученные с использованием различных методик добавления данных в элемент управления TreeView и их исключения из него, приведены в таблицах 11.1 и 11.2.

Таблица 11.1. Физическое устройство Pocket PC: добавление 800 элементов данных (время в секундах)

Номер теста Не оптимизированный подход Использование методов BeginUpdate()/EndUpdate() Использование массива
1 40,785 12,484 10,388
2 40,533 12,322 10,419
3 40,878 13,343 11,686
Среднее 40,732 12,716 10,831
Экономия времени по сравнению с базовым значением Базовое значение (0%) 68,78% 73,41%

Из табл. 11.1 видно, что экономия времени, достигаемая за счет окружения кода, предназначенного для добавления в элемент управления TreeView и исключения из него данных, вызовами методов BeginUpdate() и EndUpdate(), составила примерно две трети (68,78%). Наряду с этим, благодаря тому, что мерцание элементов управления вследствие их обновления происходит реже, повышается и привлекательность интерфейса, оцениваемая с позиций конечного пользователя. Использование метода AddRange() (столбец "Использование массива") для заполнения данными элемента управления TreeView позволило уменьшить накладные расходы еще на 5%; это улучшение также является ощутимым.

Было довольно-таки неожиданно обнаружить, что использование пары вызовов BeginUpdate() и EndUpdate() привело не только к значительному увеличению скорости добавления данных в элемент управления TreeView, но и оказало достаточно сильное влияние на скорость их удаления. Результаты, полученные с использованием двух различных подходов для удаления данных из элемента управления TreeView, сравниваются в табл. 11.2.

Таблица 11.2. Очистка 800 элементов данных (время в секундах)

Номер теста Не оптимизированный подход Использование методов BeginUpdate()/EndUpdate()
1 18,791 8,656
2 15,910 8,964
3 16,821 8,516
Среднее 17,174 8,712
Экономия времени по сравнению с базовым значением Базовое значение (0 %) 49,27 %

Как видно из табл. 11.2, одного лишь окружения кода, предназначенного для удаления данных из элемента управления TreeView, вызовами методов BeginUpdate() и EndUpdate() оказалось достаточным для того, чтобы достигнуть 50%-ной экономии времени.

На основании полученных результатов можно сделать следующие выводы:

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

2. Было бы неправильно предполагать, будто такие концептуально простые операции, как, например, очистка элемента управления от данных, будут сами по себе выполняться быстро и поэтому не следует прилагать никаких усилий к их ускорению.

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

Оглавление книги


Генерация: 0.606. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз