Diferencias de rendimiento sorprendentes: List.Constains, SortedList.ContainsKey, DataRowCollection.Contains, DataTable.Select, DataTable.FindBy

Originalmente, quería pedir la forma más rápida de consultar una tabla de datos para una fila especial.

He probado 5 métodos diferentes para su rendimiento con un resultado sorprendente (para mí).

Antecedentes: he creado una vista en una base de datos MS Sql-Server 2005. Esta vista tiene un recuento total actual de 6318 filas. Debido a que debo verificar muy a menudo si existe una identificación determinada en esta vista, me preguntaba cuál es la forma más eficiente de hacerlo. Creé un DataAdapter en un conjunto de datos fuertemente tipado que devuelve todas las filas y llena una tabla de datos. Mi primer enfoque fue crear una Lista genérica compartida (de Int32) y llenarla con los ID de la vista una vez que se inicia la Aplicación. Luego usaLista Contiene para verificar si la identificación actual está en esta lista. Debido a que todas las filas son distintas, me preguntaba si no es más rápido usar una SortedList y suContiene claveMetod. Luego verifiqué también el rendimiento del acceso directo al Datable con suMétodo de selección, se genera automáticamente (cuando la columna se define como clave principal)Método FindBy y por último pero no menos importanteDatarowCollection.Contains-Método. Entonces, tengo 5 métodos para verificar si mi ID está en esa vista (o en la lista / lista ordenada).

Medí su desempeño con elSystem.Diagnostics.StopWatch y obtuve algunos resultados interesantes. Pensé que SortedList.ContainsKey debe ser más rápido que List.Contains porque son distintos y están ordenados, pero lo contrario es cierto. Pero lo más sorprendente para mí fue que DataRowCollection.Contains-Method (que primero había olvidado) es, con mucho, el más rápido. Es incluso 50 veces más rápido que el método dataTable.FindBy.

¿Qué causó estas diferencias?¿He olvidado una mejor manera?¿Es correcto mi método de medición (creo que mejor debería recorrerlos y tomar esos valores)?¿Los valores son transferibles o dependen del tamaño de la tabla de datos / colección?Después de mi actualización (1000000 iteraciones) ContainsKey es la más rápida. ¿Es esto porque siempre verifico la misma identificación o en general? ¿Hay algún tipo de SortedList sin la sobrecarga del KeyValue-Pair de un diccionario?

Resultados [para 1000000 iteraciones *]

Intervalo de tiempo 1 =SortedList.ContainsKey = Ø 0.65634 [238,1095] SraTimespan 2 =Lista Contiene = Ø 0.06802 [57045.37955] SraPeriodo de tiempo 3 =DataTable.FindByIdData(método autogenerado) = Ø 0.31580 [1542.62345] SraTimespan 4 =DataTable.Select = Ø 0.27790 [26029.39635] Sra

Timespan 5 =DataRowCollection.Contains = Ø 0.00638 [1202.79735] Sra

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

Y en aras de la integridad parte de laFuente 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"

ACTUALIZAR: He cambiado mis resultados y la fuente anterior. Entre corchetes se encuentran los valores para 1000000 iteraciones. Ahora el resultado es completamente diferente. El método más rápido ahora es definitivamente la ContainsKey de SortedList.

ACTUALIZACIÓN 2: Olvidé la alternativa a usarList.BinarySearch. Esto parece ser más rápido para mí:

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

solo necesita 219.1805 ms para realizar 1000000 iteraciones y, por lo tanto, es el más rápido sin la sobrecarga de SortedList-KeyValue-Pair. Puedo usarlo sin ordenar la lista porque DataAdapter llenó la tabla de datos con una cláusula Order By.

Respuestas a la pregunta(3)

Su respuesta a la pregunta