Книга: Программирование мобильных устройств на платформе .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
- Листинг 14.1. Простой пример создания и использования объекта ADO.NET DataSet
- Листинг 14.2. Использование параметра XMLWriteMode при сохранении объекта ADO.NET DataSet
- Листинг 14.3. Сравнение производительности различных вариантов доступа к данным с использованием объектов DataSet
- Листинг 14.4. Результаты тестирования производительности при использовании пользовательского формата данных вместо объектов DataSet
- Листинг 14.5. Пример пользовательского управления данными — код, помещаемый в форму Form1.cs
- Листинг 14.6. Пример кода управления данными для DatabaseAccess.cs
- Листинг 14.7. Пример кода управления данными для GameData.cs
- Листинг 14.8. Пример кода управления данными для VocabularyWord.cs
- Листинг 10.1. (simpleid.c) Отображение идентификаторов пользователя и группы
- Восстановление с использованием инструмента gbak
- Совместимость клиентов и серверов различных версий
- Повышение производительности приложений с помощью хранимых процедур
- Иерархия объектов в InterBase
- Имена объектов длиной 68 символов
- 9.4. Права доступа к squid
- Создание объектов Collection
- 8.1.4. Сравнение массивов
- Вызов хранимых процедур InterBase с использованием стандартного синтаксиса ODBC
- 10.5. Транзакции и пути доступа меню
- Листинг 15.11. Код для загрузки файла с Web-сервера