Как сделать недействительным кеш при тестировании? - PullRequest
1 голос
/ 21 апреля 2010

У меня есть этот код, что при изменении порядка использованияAs и UsingCast их производительность также меняется.

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


}

Выходы:

As: 0 : 322
Cast: 0 : 281

При этом ...

UsingCast(values);
UsingAs(values);

... Результаты к этому:

Cast: 0 : 322
As: 0 : 281

При этом просто ...

UsingAs(values);

... Результаты к этому:

As: 0 : 322

При этом просто:

UsingCast(values);

... Результаты к этому:

Cast: 0 : 322

Кроме того, чтобы запускать их независимо, как аннулировать кэш, чтобы второй тестируемый код не получал кешированную память первого кода?

Не говоря о бенчмаркинге, просто любил тот факт, что современные процессоры делают эту магию кеширования:

[EDIT]

Как советуют попробовать этот более быстрый код (предположительно) ...

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

... Результат таков:

As and null test: 0 : 342

Медленнее, чем два кода выше

[EDIT]:

Как советовали вручать каждой рутине свою копию ...

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

... Выходы:

Cast: 0 : 282
As: 0 : 282

Теперь у них одинаковые результаты, спасибо, Ремус!

Запуск Cast и As независимо друг от друга, они также дают одинаковый результат (т.е. 282). Теперь, что касается того, почему они становятся быстрее (с 322 до 282 миллисекунд), когда им вручают свою собственную копию массива, я ничего не могу из этого сделать :-) Это совсем другая история

1 Ответ

1 голос
/ 21 апреля 2010

Если вы хотите исключить кэш L2 и TLB, то просто вызовите второй тест на другом MemoryStream того же размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...