Question

Je le code, que lorsque la permutation de l'ordre de UsingAs et UsingCast, leurs performances aussi des swaps.

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);
    }


}

Sorties:

As: 0 : 322
Cast: 0 : 281

Quand vous faites cela ...

UsingCast(values);
UsingAs(values);

... Résultats à ceci:

Cast: 0 : 322
As: 0 : 281

Quand vous faites tout cela ...

UsingAs(values);

... Résultats à ceci:

As: 0 : 322

Quand vous faites ceci:

UsingCast(values);

... Résultats à ceci:

Cast: 0 : 322

En plus de les exécuter de façon indépendante, comment invalidate le cache de sorte que le second code étant étalonnée ne recevront pas la mémoire cache du premier code?

Analyse comparative de côté, juste aimé le fait que les processeurs modernes font la magie de la mise en cache: -)

[EDIT]

Comme conseillé d'essayer ce code plus rapide (soi-disant) ...

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);
}

... Le résultat est le suivant:

As and null test: 0 : 342

lent que les deux codes ci-dessus

[EDIT]:

Comme conseillé de remettre chaque routine de leur propre copie ...

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);
}

... Sorties:

Cast: 0 : 282
As: 0 : 282

Maintenant, ils ont les mêmes résultats, merci Remus!

Ensemble de course et de manière aussi autonome, ils donnent aussi le même résultat (à savoir. 282). Maintenant, pour pourquoi ils deviennent plus rapide (de 322 jusqu'à 282 millisecondes) quand ils sont remis leur propre copie du tableau, je ne peux rien faire sortir :-) C'est tout à fait une autre histoire

Était-ce utile?

La solution

Si vous voulez sortir de l'image du cache L2 et le TLB alors il suffit d'appeler le second test sur un MemoryStream différent de la même taille.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top