Cuando se utiliza un Guid como un índice para un Dictionary, es que es mejor usar la Guid objeto, o la representación de cadena de la Guid?

Acabo de refactorizar el código que se utiliza cadena de usar el objeto, porque no se new Guid() llamadas de todo el lugar. Pero que me dejó pensando lo que los problemas de rendimiento pueden ser. (Las colecciones son bastante pequeñas, pero no llegar a afirmar un montón de veces).

InformationsquelleAutor Benjol | 2009-04-03

3 Comentarios

  1. 80

    La Guid debe ser más rápido, ya que la comparación es más sencillo – solo un par de directos bytes. La cadena consiste en una eliminación de referencias y mucho más trabajo.

    Por supuesto, podría perfil ;-p

    Evidencia:

    Searching for 7f9b349f-f36f-94de-ad96-04279ddf6ecf
    As guid: 466; -1018643328
    As string: 512; -1018643328
    Searching for 870ba465-08f2-c872-cfc9-b3cc1ffa09de
    As guid: 470; 1047183104
    As string: 589; 1047183104
    Searching for d2376f8a-b8c9-4633-ee8e-9679bb30f918
    As guid: 423; 1841649088
    As string: 493; 1841649088
    Searching for 599889e8-d5fd-3618-4c4f-cb620e6f81bb
    As guid: 488; -589561792
    As string: 493; -589561792
    Searching for fb64821e-c541-45f4-0fd6-1c772189dadf
    As guid: 450; 1389733504
    As string: 511; 1389733504
    Searching for 798b9fe5-ba15-2753-357a-7637161ee48a
    As guid: 415; 779298176
    As string: 504; 779298176
    Searching for 12ba292e-8e59-e5d0-7d04-e811a237dc21
    As guid: 457; 558250944
    As string: 564; 558250944
    Searching for 05b3ce14-dfbf-4d3a-1503-ced515decb81
    As guid: 413; 1658205056
    As string: 504; 1658205056
    Searching for 8db4a556-0a65-d8cb-4d0d-0104245d18b8
    As guid: 415; 696231936
    As string: 506; 696231936
    Searching for c49cf80c-5537-fba5-eebd-8ad21bba09c4
    As guid: 459; 2100976384
    As string: 557; 2100976384

    basado en:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    static class Program
    {
    static void Main()
    {
    Random rand = new Random(123456);
    int COUNT = 1000;
    Dictionary<Guid, int> guids = new Dictionary<Guid, int>(COUNT);
    Dictionary<string, int> strings = new Dictionary<string, int>(
    COUNT, StringComparer.Ordinal);
    byte[] buffer = new byte[16];
    for (int i = 0; i < COUNT; i++)
    {
    rand.NextBytes(buffer);
    Guid guid = new Guid(buffer);
    int val = rand.Next();
    guids.Add(guid, val);
    strings.Add(guid.ToString(), val);
    }
    for(int i = 0 ; i < 10 ; i++) {
    int index = rand.Next(COUNT);
    Guid guid = guids.Keys.Skip(index).First();
    Console.WriteLine("Searching for " + guid);
    int chk = 0;
    const int LOOP = 5000000;
    Stopwatch watch = Stopwatch.StartNew();
    for (int j = 0; j < LOOP; j++)
    {
    chk += guids[guid];
    }
    watch.Stop();
    Console.WriteLine("As guid: " + watch.ElapsedMilliseconds
    + "; " + chk);
    string key = guid.ToString();
    chk = 0;
    watch = Stopwatch.StartNew();
    for (int j = 0; j < LOOP; j++)
    {
    chk += strings[key];
    }
    watch.Stop();
    Console.WriteLine("As string: " + watch.ElapsedMilliseconds
    + "; " + chk);
    }
    Console.ReadLine();
    }
    }
    • Oh, usted no lo va a hacer por mí? 😉
    • Wow, hiciste! La respuesta es tuya, señor!
    • Servicio con una sonrisa ;-p
    • Así, la cadena es de aproximadamente 20% más rápido en esas cifras (pero incluyen más que el complemento de las operaciones). Sería interesante ver la diferencia en la búsqueda de veces.
    • En realidad, las cifras solo cubierta de la búsqueda de veces. El complemento no está perfilado.
    • uhm, que significó la cadena es de 20% más lento a la derecha?
    • umm, sí. Casi 4 años en… 🙂

  2. 2

    Las colecciones son bastante pequeñas, pero tienen reiterado muchas veces

    Si la iteración, no hay ninguna tecla de comparaciones. Si va a agregar/modificar o buscar por clave, a continuación, las claves serán hash y el hash de comparación; sólo si los hash igual que las teclas se pueden comparar.

    Por lo tanto, a menos que se realización de un montón de clave de operaciones basadas en grandes diccionarios con muchas colisiones de hash de la velocidad de la tecla de comparaciones no va a ser un factor importante.

    • Sí, mala redacción de mi parte. No hay mucho punto de tener un diccionario si no hay búsquedas!
    • Un Diccionario asegura que las claves son únicas y O(log n) la inserción; esto puede ser muy útil incluso si usted sólo va a iterar.
    • (ver respuesta a tu comentario en mi post)
    • Si usted no necesita clave/valor de la semántica, pero quiere garantizar la unicidad, un HashSet es probablemente una mejor manera de ir.
  3. 1

    Mi primer pensamiento hubiera sido, que Guid objetos son más rápidos, pero si usted consigue un poco de entrada de la cadena y tenemos que buscar en una pequeña colección (hashset) de Guid (que no cambian a menudo), que podría ser más rápido a la tienda como cadenas, porque:

    • Para buscar una cadena en un GUID-Diccionario, usted tiene que analizar la cadena (incluyendo la comprobación de errores, etc.), crear el Guid estructura, obtener el código hash, hacer el hash y de búsqueda de una comparación final de la GUID bytes.

    • Para buscar una cadena en una Cadena de Diccionario, usted tiene que construir el hash de la cadena (posiblemente más rápido que la construcción de la Guid struct), búsqueda el hash y hacer una comparación de cadenas. Si, por ejemplo, se espera que muchos de los Guid de no estar en las colecciones, la comparación de hash se producirá a menudo usted incluso no tiene que hacer la comparación de las cadenas (que tarda un poco más de tiempo que el GUID-comparación del punto 1 anterior)

    Si usted ya tiene Guid-estructuras de entrada (por ejemplo, porque hizo alguna validez de comprobación en las cadenas de entrada), por supuesto, es mucho mejor para reutilizarlos como índice en el diccionario.

    PERO: Desde el punto de vista de diseño de la claridad (que es mucho más importante que el rendimiento en el 99% de todo el código) usted debe usar Guid estructuras y el único cambio que, si realmente se ejecute en el rendimiento de los problemas (y de generación de perfiles de muestra que usted obtenga una ventaja de la cadena de solución).

Dejar respuesta

Please enter your comment!
Please enter your name here