Удивление различий в производительности: Список. Constains, SortedList. ContainsKey, DataRowCollection. Содержит, DataTable. Выбор, DataTable. FindBy

Первоначально я хотел попросить самый быстрый способ запросить Таблицу данных для специальной строки.

Я протестировал 5 различных методов на их производительность с удивлением (для меня) результат.

Фон: Я создал Представление в Базе данных SQL-сервера MS 2005 года. Это представление имеет текущий общее количество 6 318 строк. Поскольку я должен проверять очень часто, существует ли данный идентификатор в этом представлении, я задался вопросом, что состоит в том, чтобы сделать самый эффективный путь. Я создал DataAdapter в наборе данных со строгим контролем типов, который возвращает все строки и заполняет Таблицу данных. Мой первый подход должен был создать общий универсальный Список (Int32) и заполнить его идентификатором от представления, после того как на Приложении запускаются. Затем используйте Список. Содержит, чтобы проверить, находится ли текущий идентификатор в этом Списке. Поскольку все строки отличны, я задался вопросом если не быстрее для использования SortedList и его ContainsKey-metod. Затем я проверил также выполнение прямого доступа к Поддающемуся датировке с ее Избранным Методом, ее автоматически сгенерированный (когда столбец определяется как первичный ключ), FindBy-метод и наконец, что не менее важно, DatarowCollection. Содержать-метод. Таким образом, у меня есть 5 Методов, чтобы проверить, находится ли мой идентификатор в том Представлении (или отображенный List/SortedList).

Я измерил их уровень с Системой. Диагностика. StopWatch и получил некоторые интересные результаты. Я думал SortedList. ContainsKey должен быть быстрее, чем Список. Содержит, потому что они отличны и отсортированы, но противоположное верно. Но самое удивительное для меня было то, что DataRowCollection. Содержать-метод (что я сначала забыл) является безусловно самым быстрым. Это даже в 50 раз быстрее, чем таблица данных. FindBy-метод.

  1. Что вызвало эти различия?
  2. Я забыл лучший путь?
  3. Мой метод измерения корректен (я думаю, что лучше должен циклично выполнить их и взять, который оценивает)?
  4. Значения передаваемы или зависят от размера Таблицы данных/Набора?
  5. После моего обновления (1 000 000 повторений) ContainsKey является самым быстрым. Это вызвано тем, что я всегда проверяю на тот же идентификатор или в целом? Есть ли некоторый SortedList без издержек KeyValue-парного Словаря?

Результаты [для 1 000 000 повторений*]

  • Промежуток 1 = SortedList. ContainsKey = Ø 0,65634 [238.1095] мс
  • Промежуток 2 = Список. Содержит = Ø 0,06802 [57045.37955] мс
  • Промежуток 3 = DataTable. FindByIdData (автоматически сгенерированный метод) = Ø 0,31580 [1542.62345] мс
  • Промежуток 4 = DataTable. Выберите = Ø 0,27790 [26029.39635] мс
  • Промежуток 5 = DataRowCollection. Содержит = Ø 0,00638 [1202.79735] мс

    1.)
    Timespan 1: 0,6913 ms
    Timespan 2: 0,1053 ms
    Timespan 3: 0,3279 ms
    Timespan 4: 0,1002 ms
    Timespan 5: 0,0056 ms
    
    2.)
    Timespan 1: 0,6405 ms
    Timespan 2: 0,0588 ms
    Timespan 3: 0,3112 ms
    Timespan 4: 0,3872 ms
    Timespan 5: 0,0067 ms
    
    3.)
    Timespan 1: 0,6502 ms
    Timespan 2: 0,0588 ms
    Timespan 3: 0,3092 ms
    Timespan 4: 0,1268 ms
    Timespan 5: 0,007 ms
    
    4.)
    Timespan 1: 0,6504 ms
    Timespan 2: 0,0586 ms
    Timespan 3: 0,3092 ms
    Timespan 4: 0,3893 ms
    Timespan 5: 0,0063 ms
    
    5.)
    Timespan 1: 0,6493 ms
    Timespan 2: 0,0586 ms
    Timespan 3: 0,3215 ms
    Timespan 4: 0,386 ms
    Timespan 5: 0,0063 ms
    
    
    
    Timespan 1: 0,6913 0,6405 0,6502 0,6504 0,6493 = Ø 0,65634
    Timespan 2: 0,1053 0,0588 0,0588 0,0586 0,0586 = Ø 0,06802
    Timespan 3: 0,3279 0,3112 0,3092 0,3092 0,3215 = Ø 0,31580
    Timespan 4: 0,1002 0,3872 0,1268 0,3893 0,3860 = Ø 0,27790
    Timespan 5: 0,0056 0,0067 0,0070 0,0063 0,0063 = Ø 0,00638
    

И ради части полноты источника VB.Net:

Dim applies As Boolean
Dim clock As New System.Diagnostics.Stopwatch

clock.Start()
For i As Int32 = 1 To 1000000
    applies = sortedListAC17NextClaims.ContainsKey(myClaim.idData)
Next
clock.Stop()
Dim timeSpan1 As String = "Timespan 1: " & clock.Elapsed.TotalMilliseconds.ToString & " ms"

clock.Reset()
clock.Start()
For i As Int32 = 1 To 1000000
    applies = listAC17NextClaims.Contains(myClaim.idData)
Next
clock.Stop()
Dim timeSpan2 As String = "Timespan 2: " & clock.Elapsed.TotalMilliseconds.ToString & " ms"

clock.Reset()
clock.Start()
For i As Int32 = 1 To 1000000
    applies = Not MyDS.AC17NextClaims.FindByIdData(myClaim.idData) Is Nothing
Next
clock.Stop()
Dim timeSpan3 As String = "Timespan 3: " & clock.Elapsed.TotalMilliseconds.ToString & " ms"

clock.Reset()
clock.Start()
For i As Int32 = 1 To 1000000
    applies = MyDS.AC17NextClaims.Select("idData=" & myClaim.idData).Length > 0
Next
clock.Stop()
Dim timeSpan4 As String = "Timespan 4: " & clock.Elapsed.TotalMilliseconds.ToString & " ms"

clock.Reset()
clock.Start()
For i As Int32 = 1 To 1000000
    applies = MyDS.AC17NextClaims.Rows.Contains(myClaim.idData)
Next
clock.Stop()
Dim timeSpan5 As String = "Timespan 5: " & clock.Elapsed.TotalMilliseconds.ToString & " ms"
  • ОБНОВЛЕНИЕ: Я изменил свои результаты и источник выше. В скобках в квадрате значения для 1 000 000 повторений. Теперь результат полностью отличается. Самый быстрый метод теперь, определенно ContainsKey SortedList.

  • ОБНОВЛЕНИЕ 2: Я забыл альтернативу для использования Списка. BinarySearch. Это, кажется, является самым быстрым для меня:

    clock.Start()
    For i As Int32 = 1 To 1000000
        applies = listAC17NextClaims.BinarySearch(myClaim.idData) > -1
    Next
    clock.Stop()
    

    потребности только 219,1805 мс для выполнения 1 000 000 повторений и следовательно являются самыми быстрыми без издержек SortedList-KeyValue-Pair. Я могу использовать его без отсортировать список, потому что DataAdapter заполнил таблицу данных Порядком пунктом.

6
задан Tim Schmelter 28 July 2010 в 16:57
поделиться