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

Листинг 14.3. Сравнение производительности различных вариантов доступа к данным с использованием объектов DataSet

Листинг 14.3. Сравнение производительности различных вариантов доступа к данным с использованием объектов DataSet

System.Data.DataSet m_myDataSet; //Объект Dataset для теста
//Индексы столбцов и таблицы, подлежащие кэшированию
private bool m_indexesLookedUp = false;
private const int INVALID_INDEX = -1;
private int m_IndexOfTestColumn_CreditCard = INVALID_INDEX;
private int m_IndexOfTestColumn_TravelDate = INVALID_INDEX;
private int m_IndexOfTestTable = INVALID_INDEX;
//Столбцы данных и таблица, подлежащие кэшированию
System.Data.DataColumn m_TestColumn_CreditCard;
System.Data.DataColumn m_TestColumn_TravelDate;
private System.Data.DataTable m_TableCustomerInfo;
//3 вида тестов, которые мы можем выполнять
public enum testType {
 textColumnLookup, cachedIndexLookup, cachedColumnObject
}
//Эти константы определяют размерные характеристики тестов
const int DUMMY_ROWS_OF_DATA = 100;
const int NUMBER_TEST_ITERATIONS = 500;
//Табличная информация
const string TABLE_NAME_PASSENGERINFO = "CustomerTravelInfo";
const string COLUMN_NAME_DATE_OF_TRAVEL = "DateOfTravel";
const string COLUMN_NAME_PASSENGER_NAME = "PassengerName";
const string COLUMN_NAME_PASSENGER_CREDIT_CARD = "PassengerCreditCard";
const string TEST_CREDIT_CARD = "IvoCard-987-654-321-000";
//--------------------
//Создает набор данных
//--------------------
private void createDataSet() {
 //1. Создать новый объект DataSet
 m_myDataSet = new System.Data.DataSet("TravelService Dataset");
 //2. Добавить объект DataTable в объект ADO.NET DataSet
 System.Data.DataTable myTestTable;
 myTestTable = m_myDataSet.Tables.Add(TABLE_NAME _PASSENGERINFO);
 //Добавить 2 столбца в таблицу
 //Добавить столбец данных в таблицу DataTable набора данных DataSet
 myTestTable.Columns.Add(COLUMN_NAME_DATE_OF_TRAVEL,typeof(System.DateTime));
 //Добавить столбец строк в таблицу DataTable набора данных
 DataSet myTestTable.Columns.Add(COLUMN_NAME_PASSENGER NAME,typeof(string));
 //Добавить столбец строк в таблицу DataTable набора данных DataSet
 myTestTable.Columns.Add(COLUMN_NAME_PASSENGER_CREDIT_CARD,typeof(string));
 //Данные для размещения в строках данных
 object[] objArray;
 objArray = new object[3];
 //--------------------------------
 //Добавить строки данных в таблицу
 //--------------------------------
 System.Text.StringBuilder buildTestString;
 buildTestString = new System.Text.StringBuilder();
 for (int addItemsCount = 0; addItemsCount < DUMMY_ROWS_OF_DATA; addItemsCount++) {
  //Выбрать день отъезда пассажира
  objArray[0] = System.DateTime.Today.AddDays(addItemsCount);
  //Выбрать имя пассажира
  buildTestString.Length = 0;
  buildTestString.Append("TestPersonName");
  buildTestString.Append(addItemsCount);
  objArray[1] = buildTestString.ToString();
  //Связать с пассажиром текстовый номер кредитной карточки
  buildTestString.Length = 0;
  buildTestString.Append("IvoCard-000-000-0000-");
  buildTestString.Append(addItemsCount);
  objArray[2] = buildTestString.ToString();
  //Добавить элементы массива в строку набора данных
  myTestTable.Rows.Add(objArray);
 }
 //Добавить элемент, поиск которого мы хотим проводить при выполнении теста
 objArray[0] = System.DateTime.Today;
 objArray[1] = "Ms. TestPerson";
 objArray[2] = TEST_CREDIT_CARD;
 //Добавить элементы массива в строку набора данных
 myTestTable.Rows.Add(objArray);
} //Конец функции
//---------------------------------------------------------------
//Найти и кэшировать все индексы набора данных, которые нам нужны
//---------------------------------------------------------------
private void cacheDataSetInfo() {
 //Выйти из функции, если индексы уже загружены
 if (m_indexesLookedUp == true) {
  return;
 }
 //Кэшировать индекс таблицы
 m_IndexOfTestTable = m_myDataSet.Tables.IndexOf(TABLE_NAME_PASSENGERINFO);
 //------------------------------------------
 //Итерировать по всем столбцам нашей таблицы
 //и кэшировать индексы нужных столбцов
 //------------------------------------------
 m_TableCustomerInfo = m_myDataSet.Tables[m_IndexOfTestTable];
 int dataColumnCount = m_TableCustomerInfo.Columns.Count;
 System.Data.DataColumn myColumn;
 for (int colIdx = 0; colIdx < dataColumnCount;) {
  myColumn = m_TableCustomerInfo.Columns[colIdx];
  //Предпринимать поиск, только если это еще не сделано
  if (m_IndexOfTestColumn_CreditCard == INVALID_INDEX) {
   //Проверить, совпадает ли имя
   if (myColumn.ColumnName == COLUMN_NAME_PASSENGER_CREDIT_CARD) {
    //Кэшировать индекс
    m_IndexOfTestColumn_CreditCard = colIdx;
    //Кэшировать столбец
    m_TestColumn_CreditCard = myColumn;
    goto next_loop_iteration; //Опустить другие операции сравнения...
   } //Endif: сравнение строк
  } //Endif
  if (m_IndexOfTestColumn_TravelDate == INVALID_INDEX) {
   //Проверить, совпадает ли имя
   if (myColumn.ColumnName == COLUMN_NAME_DATE_OF_TRAVEL) {
    //Кэшировать индекс
    m_IndexOfTestColumn_TravelDate = colIdx;
    //Кэшировать столбец
    m_TestColumn_TravelDate = myColumn;
    goto next_loop_iteration; //Опустить другие операции сравнения.
   } //Endif: сравнение строк
  } //Endif
next_loop_iteration:
  colIdx++;
 }
 m_indexesLookedUp =true;
}
//--------------
//Выполнить тест
//--------------
void changeDayOfTravel_test(testType kindOfTest) {
 //Отобразить курсор ожидания
 System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
 //Начать с известной даты...
 System.DateTime newDate;
 newDate = System.DateTime.Today;
 changeDayOfTravel_textColumnLookup(ТЕST_CREDIT_CARD, newDate);
 //ДОПУСТИМО ТОЛЬКО ДЛЯ ТЕСТОВОГО КОДА!!!
 //Вызов сборщика мусора в коде ЗАМЕДЛИТ работу вашего приложения!
 System.GC.Collect();
 const int testNumber = 0;
 //Настроить соответствующим образом в зависимости от вида выполняемого теста
 switch (kindOfTest) {
 case testType.textColumnLookup:
  PerformanceSampling.StartSample(testNumber, "Text based Column lookup.");
  break;
 case testType.cachedIndexLookup:
  PerformanceSampling.StartSample(testNumber, "Cached Column Index lookup.");
  break;
 case testType.cachedColumnObject:
  PerformanceSampling.StartSample(testNumber, "Cached Column objects");
  break;
 default:
  throw new Exception("Unknown state!");
 }
 //Выполнить тест!
 for (int testCount = 0; testCount < NUMBER_TEST_ITERATIONS; testCount++) {
  //Передвинуть дату вперед на один день
  newDate = newDate.AddDays(1);
  int numberRecordsChanged = 0;
  //Какой вид теста мы выполняем?
  switch (kindOfTest) {
  case testType.textColumnLookup:
   //НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Просмотреть все имена, используя СТРОКИ
   numberRecordsChanged =
    changeDayOfTravel_textColumnLookup(ТЕST_CREDIT_CARD, newDate);
   break;
  case testType.cachedIndexLookup:
   //ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированные индексы
   numberRecordsChanged =
    changeDayOfTravel_cachedColumnIndex(ТЕST_CREDIT_CARD, newDate);
   break;
  case testType.cachedColumnObject:
   //НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированные объекты
   //столбцов
   numberRecordsChanged =
    changeDayOfTravel_CachedColumns(TEST_CREDIT_CARD, newDate);
   break;
  }
  //Убедиться в том, что тест выполняется, как и ожидалось...
  if (numberRecordsChanged != 1) {
   System.Windows.Forms.MessageBox.Show("No matching records found. Test aborted!");
   return;
  }
 }
 //Получить время, которое потребовалось для выполнения теста
 PerformanceSampling.StopSample(testNumber);
 //Обычный курсор
 System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
 //Отобразить результаты выполнения теста
 string runInfo = NUMBER_TEST_ITERATIONS.ToString() + "x" +
  DUMMY_ROWS_OF_DATA.ToString() + ": ";
 System.Windows.Forms.MessageBox.Show(runInfo +
  PerformanceSampling.GetSampleDurationText(testNumber));
}
//ФУНКЦИЯ ПОИСКА, ОБЛАДАЮЩАЯ НИЗКОЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
private int changeDayOfTravel_ textColumnLookup(string creditCardNumber, System.DateTime newTravelDate) {
 int numberRecordsChanged = 0;
 //Найти имя таблицы
 System.Data.DataTable dataTable_Customers;
 //НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск в таблице, используя
 //сравнение строк!
 dataTable_Customers = m_myDataSet.Tables[TABLE_NAME_PASSENGERINFO];
 foreach (System.Data.DataRow currentCustomerRow in dataTable_Customers.Rows) {
  string currentCreditCard;
  //НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск в таблице, используя
  //сравнение строк!
  currentCreditCard = (string)currentCustomerRow[COLUMN_NAME_PASSENGER_CREDIT_CARD];
  //Проверить, является ли данная кредитная карточка искомой
  if (creditCardNumber == currentCreditCard) {
   //Изменить дату отъезда
   //НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск столбца, используя
   //сравнение строк!
   System.DateTime currentTravelDate =
    (System.DateTime)currentCustomerRow[COLUMN_NAME_DATE_OF_TRAVEL];
   if (currentTravelDate != newTravelDate) {
    //НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск столбца, используя
    //сравнение строк!
    currentCustomerRow[COLUMN_NAME_DATE_OF_TRAVEL] = newTravelDate;
    numberRecordsChanged++;
   }
  } //endif: сравнение строк
 } //end foreach
 return numberRecordsChanged; //Количество обновленных записей
}
//ФУНКЦИЯ, ХАРАКТЕРИЗУЮЩАЯСЯ НЕСКОЛЬКО ЛУЧШЕЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
private int changeDayOfTravel_cachedColumnIndex(string creditCardNumber, System.DateTime newTravelDate) {
 int numberRecordsChanged = 0;
 //Поиск имени таблицы
 System.Data.DataTable dataTable_Customers;
 //ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: использовать кэшированный индекс
 dataTable_Customers = m_myDataSet.Tables[m_IndexOfTestTable];
 foreach (System.Data.DataRow currentCustomerRow in dataTable_Customers.Rows) {
  string currentCreditCard;
  //ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: использовать кэшированный индекс столбца!
  currentCreditCard =
   (string)currentCustomerRow[m_IndexOfTestColumn_CreditCard];
  //Проверить, совпадает ли номер кредитной карточки...
  if (creditCardNumber == currentCreditCard) {
   //Изменить дату отъезда
   //ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
   System.DateTime currentTravelDate =
    (System.DateTime)currentCustomerRow[m_IndexOfTestColumn_TravelDate];
   if (currentTravelDate != newTravelDate) {
    //ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс
    //столбца!
    currentCustomerRow[m_IndexOfTestColumn_TravelDate] = newTravelDate;
    numberRecordsChanged++;
   }
  }
 }
 return numberRecordsChanged; //Количество обновленных записей
}
//ФУНКЦИЯ, ОБЛАДАЮЩАЯ НАИЛУЧШЕЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
private int changeDayOfTravel_CachedColumns(string creditCardNumber, System.DateTime newTravelDate) {
 int numberRecordsChanged = 0;
 //Найти имя таблицы
 System.Data.DataTable dataTable_Customers = m_TableCustomerInfo;
 foreach (System.Data.DataRow currentCustomerRow in dataTable_Customers.Rows) {
  string currentCreditCard;
  //НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
  currentCreditCard =
   (string)currentCustomerRow[m_TestColumn CreditCard];
  //Проверить, совпадает ли номер кредитной карточки...
  if (creditCardNumber == currentCreditCard) {
   //Изменить дату отъезда
   //НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
   System.DateTime currentTravelDate =
    (System.DateTime)currentCustomerRow[m_TestColumn_TravelDate];
   if (currentTravelDate != newTravelDate) {
    //НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс
    //столбца!
    currentCustomerRow[m_TestColumn TravelDate] = newTravelDate;
    numberRecordsChanged++;
   }
  }
 }
 return numberRecordsChanged; //Количество обновленных записей
}
//Событие щелчка на кнопке
private void buttonRunTest_Click(object sender, System.EventArgs e) {
 createDataSet();
 cacheDataSetInfo();
 //НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по строкам
 changeDayOfTravel_test(testType.textColumnLookup);
 //ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по целочисленным индексам
 changeDayOfTravel_test(testType.cachedIndexLookup);
 //НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по объектам столбцов
 changeDayOfTravel_test(testType.cachedColumnObject);
}

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

Оглавление статьи/книги

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