Pregunta

Tengo este código, que cuando se cambia el orden de UsingAs y UsingCast, su rendimiento también permutas.

using System;
using System.Diagnostics;
using System.Linq;

using System.IO;

class Test
{
    const int Size = 30000000;

    static void Main()
    {
        object[] values = new MemoryStream[Size];



        UsingAs(values);
        UsingCast(values);


        Console.ReadLine();
    }

    static void UsingCast(object[] values)
    {
        Stopwatch sw = Stopwatch.StartNew();
        int sum = 0;
        foreach (object o in values)
        {
            if (o is MemoryStream)
            {
                var m = (MemoryStream)o;
                sum += (int)m.Length;
            }
        }
        sw.Stop();
        Console.WriteLine("Cast: {0} : {1}", sum,
                          (long)sw.ElapsedMilliseconds);
    }

    static void UsingAs(object[] values)
    {
        Stopwatch sw = Stopwatch.StartNew();
        int sum = 0;
        foreach (object o in values)
        {

            if (o is MemoryStream)
            {
                var m = o as MemoryStream;
                sum += (int)m.Length;
            }
        }
        sw.Stop();
        Console.WriteLine("As: {0} : {1}", sum,
                          (long)sw.ElapsedMilliseconds);
    }


}

Salidas:

As: 0 : 322
Cast: 0 : 281

Al hacer esto ...

UsingCast(values);
UsingAs(values);

... Resultados para esto:

Cast: 0 : 322
As: 0 : 281

Al hacer esto solo ...

UsingAs(values);

... Resultados para esto:

As: 0 : 322

Al hacer esto:

UsingCast(values);

... Resultados para esto:

Cast: 0 : 322

Además de correr de forma independiente, la forma de invalidate la caché por lo que el segundo código siendo punto de referencia no recibirán la memoria caché del primer código?

La evaluación comparativa a un lado, le encantó el hecho de que los procesadores modernos hacen caché de magia: -)

[EDIT]

Como aconsejó a probar este código más rápido (supuestamente) ...

static void UsingAsAndNullTest(object[] values)
{        
    Stopwatch sw = Stopwatch.StartNew();
    int sum = 0;
    foreach (object o in values)
    {
        var m = o as MemoryStream;
        if (m != null)
        {                
            sum += (int)m.Length;
        }
    }
    sw.Stop();
    Console.WriteLine("As and null test: {0} : {1}", sum,
                      (long)sw.ElapsedMilliseconds);
}

... El resultado es el siguiente:

As and null test: 0 : 342

Más lento que los dos códigos anteriormente

[EDIT]:

Como aconsejó a mano cada rutina de su propia copia ...

static void UsingAs(object[] values)
{
    object[] a = values.ToArray();

    Stopwatch sw = Stopwatch.StartNew();
    int sum = 0;
    foreach (object o in a)
    {

        if (o is MemoryStream)
        {
            var m = o as MemoryStream;
            sum += (int)m.Length;
        }
    }
    sw.Stop();
    Console.WriteLine("As: {0} : {1}", sum,
                      (long)sw.ElapsedMilliseconds);
}

static void UsingCast(object[] values)
{
    object[] a = values.ToArray();

    Stopwatch sw = Stopwatch.StartNew();
    int sum = 0;
    foreach (object o in a)
    {
        if (o is MemoryStream)
        {
            var m = (MemoryStream)o;
            sum += (int)m.Length;
        }
    }
    sw.Stop();
    Console.WriteLine("Cast: {0} : {1}", sum,
                      (long)sw.ElapsedMilliseconds);
}

... Salidas:

Cast: 0 : 282
As: 0 : 282

Ahora tienen los mismos resultados, gracias Remus!

Funcionamiento moldeada y lo más independientemente, sino que también dan el mismo resultado (es decir. 282). Ahora, en cuanto a por qué se vuelven rápido (de 322 a 282 milisegundos) cuando son entregados a su propia copia de la matriz, no puede hacer nada de él :-) Eso es totalmente otra historia

¿Fue útil?

Solución

Si usted quiere tomar fuera de la imagen de la memoria caché L2 y la TLB entonces simplemente llamar a la segunda prueba en un MemoryStream diferente del mismo tamaño.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top