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

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

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

Private m_myDataSet As System.Data.DataSet 'Набор данных для тестирования
'Индексы столбцов и таблицы, подлежащие кэшированию
Private m_indexesLookedUp As Boolean = False
Private Const INVALID_INDEX As Integer = -1
Private m_IndexOfTestColumn_CreditCard _
 As Integer = INVALID_INDEX
Private m_IndexOfTestColumn_TravelDate _
 As Integer = INVALID_INDEX
Private m_IndexOfTestTable As Integer = INVALID_INDEX
'Столбцы данных и таблица, подлежащих кэшированию
Private m_TestColumn_CreditCard As System.Data.DataColumn
Private m_TestColumn_TravelDate As System.Data.DataColumn
Private m_TableCustomerInfo As System.Data.DataTable
Public Enum testType '3 вида тестов, которые мы можем выполнять
 textColumnLookup
 cachedIndexLookup
 cachedColumnObject
End Enum
'Эти константы определяют размерные характеристики тестов
Const DUMMY_ROWS_OF_DATA As Integer = 100
Const NUMBER_TEST_ITERATIONS As Integer = 500
'Табличная информация
Const TABLE_NAME_PASSENGERINFO As String = "CustomerTravelInfo"
Const COLUMN_NAME_DATE_OF_TRAVEL As String = "DateOfTravel"
Const COLUMN_NAME_PASSENGER_NAME As String = "PassengerName"
Const COLUMN_NAME_PASSENGER_CREDIT_CARD As String = _
 "PassengerCreditCard"
Const TEST_CREDIT_CARD As String = "IvoCard-987-654-321-000"
'--------------------
'Создает набор данных
'--------------------
Private Sub createDataSet()
 '1. Создать новый объект DataSet
 m_myDataSet = New System.Data.DataSet("TravelService Dataset")
 '2. Добавить объект DataTable в объект ADO.NET DataSet
 Dim myTestTable As System.Data.DataTable
 myTestTable = m_myDataSet.Tables.Add(TABLE_NAME_PASSENGERINFO)
 'Добавить 2 столбца в таблицу
 'Добавить столбец данных в таблицу DataTable набора данных DataSet
 myTestTable.Columns.Add(COLUMN_NAME_DATE_OF_TRAVEL, _
  GetType(System.DateTime))
 'Добавить столбец строк в таблицу DataTable набора данных DataSet
 myTestTable.Columns.Add(COLUMN_NAME_PASSENGER_NAME, _
  GetType(String))
 'Добавить столбец строк в таблицу DataTable набора данных DataSet
 myTestTable.Columns.Add(COLUMN_NAME_PASSENGER_CREDIT_CARD, _
  GetType(String))
 'Данные для размещения в строках данных
 Dim objArray() As Object ReDim objArray(2)
 '--------------------------------
 'Добавить строки данных в таблицу
 '--------------------------------
 Dim buildTestString As System.Text.StringBuilder
 buildTestString = New System.Text.StringBuilder
 Dim addItemsCount As Integer
 For addItemsCount = 1 To DUMMY_ROWS_OF_DATA
  'Выбрать день отъезда пассажира
  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)
 Next
 'Добавить элемент, поиск которого мы хотим проводить при выполнении теста
 objArray(0) = System.DateTime.Today
 objArray(1) = "Ms. TestPerson"
 objArray(2) = ТЕST_CREDIT_CARD
 'Добавить элементы массива в строку набора данных
 myTestTable.Rows.Add(objArray)
End Sub
'---------------------------------------------------------------
'Найти и кэшировать все индексы набора данных, которые нам нужны
'---------------------------------------------------------------
Private Sub cacheDataSetInfo()
 'Выйти из функции, если индексы уже загружены
 If (m_indexesLookedUp = True) Then Return
 'Кэшировать индекс таблицы
 m_IndexOfTestTable = _
  m_myDataSet.Tables.IndexOf(TABLE_NAME_PASSENGERINFO)
 '------------------------------------------
 'Итерировать по всем столбцам нашей таблицы
 'и кэшировать индексы нужных столбцов
 '------------------------------------------
 mTableCustomerInfo = m_myDataSet.Tables(m_IndexOfTestTable)
 Dim dataColumnCount As Integer
 dataColumnCount = m_TableCustomerInfo.Columns.Count
 Dim myColumn As System.Data.DataColumn
 Dim colIdx As Integer
 While (colIdx < dataColumnCount)
  myColumn = m_TableCustomerInfo.Columns(colIdx)
  'Предпринимать поиск, только если это еще не сделано
  If (m_IndexOfTestColumn_CreditCard = INVALID_INDEX) Then
   'Проверить, совпадает ли имя
   If (myColumn.ColumnName = _
    COLUMN_NAME_PASSENGER_CREDIT_CARD) Then
    'Кэшировать индекс
    m_IndexOfTestColumn_CreditCard = colIdx
    'Кэшировать столбец
    m_TestColumn_CreditCard = myColumn
    GoTo next_loop_iteration 'Опустить другие операции сравнения...
   End If 'Endif: сравнение строк
  End If
  If (m _IndexOfTestColumn_TravelDate = INVALID_INDEX) Then
   'Проверить, совпадает ли имя
   If (myColumn.ColumnName = _
    COLUMN_NAME_DATE_OF_TRAVEL) Then
    'Кэшировать индекс
    m_IndexOfTestColumn_TravelDate = colIdx
    'Кэшировать столбец
    m_TestColumn_TravelDate = myColumn
    GoTo next_loop_iteration 'Опустить другие операции сравнения
   End If 'Endif: сравнение строк
  End If
next_loop_iteration:
  colIdx = colIdx + 1
 End While
 m_indexesLookedUp = True
End Sub
'---------------
'Выполнить тест.
'---------------
Sub changeDayOfTravel_test(ByVal kindOfTest As testType)
 'Отобразить курсор ожидания
 System.Windows.Forms.Cursor.Current = _
  System.Windows.Forms.Cursors.WaitCursor
 'Начать с известной даты
 Dim newDate As System.DateTime
 newDate = System.DateTime.Today
 changeDayOfTravel_textColumnLookup(TEST_CREDIT_CARD, newDate)
 'ДОПУСТИМО ТОЛЬКО ДЛЯ ТЕСТОВОГО КОДА!!!
 'Вызов сборщика мусора в коде ЗАМЕДЛИТ работу вашего приложения!
 System.GC.Collect()
 Const testNumber As Integer = 0
 'Настроить соответствующим образом в зависимости от вида выполняемого теста
 Select Case (kindOfTest)
 Case testType.textColumnLookup
  PerformanceSampling.StartSample(testNumber, _
   "Text based Column lookup.")
 Case testType.cachedIndexLookup
  PerformanceSampling.StartSample(testNumber, _
   "Cached Column Index lookup.")
 Case testType.cachedColumnObject
  PerformanceSampling.StartSample(testNumber, _
   "Cached Column objects")
 Case Else
  Throw New Exception("Unknown state!")
 End Select
 'Выполнить тест!
 Dim testCount As Integer
 For testCount = 1 To NUMBER_TEST_ITERATIONS
  'Передвинуть дату вперед на один день
  newDate = newDate.AddDays(1)
  Dim numberRecordsChanged As Integer = 0
  'Какой вид теста мы выполняем?
  Select Case (kindOfTest)
  Case testType.textColumnLookup
   'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Просмотреть все имена, используя СТРОКИ
   numberRecordsChanged = _
    changeDayOfTravel_textColumnLookup( _
    TEST_CREDIT_CARD, newDate)
  Case testType.cachedIndexLookup
   'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированные индексы
   numberRecordsChanged = _
    changeDayOfTravel_cachedColumnIndex( _
    TEST_CREDIT_CARD, newDate)
  Case testType.cachedColumnObject
   'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированные объекты
   numberRecordsChanged = _
    changeDayOfTravel_CachedColumns( _
    TEST_CREDIT_CARD, newDate)
  End Select
  'Убедиться в том, что тест выполняется, как и ожидалось
  If (numberRecordsChanged <> 1) Then
   MsgBox("No matching records found. Test aborted!")
   Return
  End If
 Next
 'Получить время, которое потребовалось для выполнения теста
 PerformanceSampling.StopSample(testNumber)
 'Обычный курсор
 System.Windows.Forms.Cursor.Current = _
  System.Windows.Forms.Cursors.Default
 'Отобразить результаты выполнения теста
 Dim runInfo As String = NUMBER_TEST_ITERATIONS.ToString() + _
  "x" + DUMMY_ROWS_OF_DATA.ToString() + ": "
 MsgBox(runInfo + _
  PerformanceSampling.GetSampleDurationText(testNumber))
End Sub
'ФУНКЦИЯ ПОИСКА, ОБЛАДАЮЩАЯ НИЗКОЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
Private Function changeDayOfTravel_textColumnLookup( _
 ByVal creditCardNumber As String, _
 ByVal newTravelDate As System.DateTime) As Integer
 Dim numberRecordsChanged As Integer
 'Найти имя таблицы
 Dim dataTable_Customers As System.Data.DataTable
 'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск в таблице, используя
 'сравнение строк!
 dataTable_Customers = _
  m_myDataSet.Tables(TABLE_NAME_PASSENGERINFO)
 Dim currentCustomerRow As System.Data.DataRow
 For Each currentCustomerRow In dataTable_Customers.Rows
  Dim currentCreditCard As String
  'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск в таблице, используя
  'сравнение строк!
  currentCreditCard = CType( _
   currentCustomerRow(COLUMN_NAME_PASSENGER_CREDIT_CARD), String)
  'Проверить, является ли данная кредитная карточка искомой
  If (creditCardNumber = currentCreditCard) Then
   'Изменить дату отъезда
   'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск столбца, используя
   'сравнение строк!
   Dim currentTravelDate As System.DateTime = CType( _
    currentCustomerRow(COLUMN_NAME_DATE_OF_TRAVEL), _
    System.DateTime)
   If (currentTravelDate <> newTravelDate) Then
    'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Осуществить поиск столбца, используя
    'сравнение строк!
    currentCustomerRow(COLUMN_NAME_DATE_OF_TRAVEL) = _
     newTravelDate
    numberRecordsChanged = numberRecordsChanged + 1
   End If
  End If 'endif: сравнение строк
 Next 'end for each
 Return numberRecordsChanged 'Количество обновленных записей
End Function
'ФУНКЦИЯ, ХАРАКТЕРИЗУЮЩАЯСЯ НЕСКОЛЬКО ЛУЧШЕЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
Private Function changeDayOfTravel_cachedColumnIndex( _
 ByVal creditCardNumber As String, ByVal newTravelDate _
 As DateTime) As Integer
 Dim numberRecordsChanged As Integer
 'Поиск имени таблицы
 Dim dataTable_Customers As System.Data.DataTable
 'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: использовать кэшированный индекс
 dataTable_Customers = _
  m_myDataSet.Tables(m_IndexOfTestTable)
 Dim currentCustomerRow As System.Data.DataRow
 For Each currentCustomerRow In dataTable_Customers.Rows
  Dim currentCreditCard As String
  'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: использовать кэшированный индекс столбца!
  currentCreditCard = CType(currentCustomerRow( _
   m_IndexOfTestColumn_CreditCard), String)
  'Проверить, совпадает ли номер кредитной карточки
  If (creditCardNumber = currentCreditCard) Then
   'Изменить дату отъезда
   'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
   Dim currentTravelDate As System.DateTime = CType( _
    currentCustomerRow (m_IndexOfTestColumn_TravelDate), System.DateTime)
   If (currentTravelDate <> newTravelDate) Then
    'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
    currentCustomerRow(m_IndexOfTestColumn_TravelDate) = _
     newTravelDate
    numberRecordsChanged = numberRecordsChanged + 1
   End If
  End If
 Next
 Return numberRecordsChanged 'Количество обновленных записей
End Function
'ФУНКЦИЯ, ОБЛАДАЮЩАЯ НАИЛУЧШЕЙ ПРОИЗВОДИТЕЛЬНОСТЬЮ
Private Function changeDayOfTravel_CachedColumns( _
 ByVal creditCardNumber As String, _
 ByVal newTravelDate As System.DateTime) As Integer
 Dim numberRecordsChanged As Integer
 'Найти имя таблицы
 Dim dataTable_Customers As System.Data.DataTable = _
  m_TableCustomerInfo
 Dim currentCustomerRow As System.Data.DataRow
 For Each currentCustomerRow In dataTable_Customers.Rows
  Dim currentCreditCard As String
  'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
  currentCreditCard = CType( _
   currentCustomerRow(m_TestColumn_CreditCard), _
   String)
  'Проверить, совпадает ли номер кредитной карточки
  If (creditCardNumber = currentCreditCard) Then
   'Изменить дату отъезда
   'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
   Dim currentTravelDate As System.DateTime = CType( _
    currentCustomerRow(m_TestColumn_TravelDate), _
    System.DateTime)
   If (currentTravelDate <> newTravelDate) Then
    'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать кэшированный индекс столбца!
    currentCustomerRow(m_TestColumn_TravelDate) = _
     newTravelDate
    numberRecordsChanged = numberRecordsChanged + 1
   End If
  End If
 Next
 Return numberRecordsChanged 'Количество обновленных записей
End Function
'Событие щелчка на кнопке
Private Sub buttonRunTest_Click(ByVal sender As Object, _
 ByVal e As System.EventArgs) Handles buttonRunTest.Click
 createDataSet()
 cacheDataSetInfo()
 'НИЗКАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по строкам
 changeDayOfTravel_test(testType.textColumnLookup)
 'ЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по целочисленным индексам
 changeDayOfTravel_test(testType.cachedIndexLookup)
 'НАИЛУЧШАЯ ПРОИЗВОДИТЕЛЬНОСТЬ: Использовать поиск по объектам столбцов
 changeDayOfTravel_test(testType.cachedColumnObject)
End Sub

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


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