Почему анонимные методы быстрее в моих тестах? - PullRequest
0 голосов
/ 26 февраля 2012

Я написал два простых приложения: 1. один, использующий анонимные методы, и 2. один с использованием простых методов.

Каждый из перечисленных методов выполняет простое действие:

int add(int n1, int n2) {return n1+n2}

И я вызываю простой цикл for, который вызовет метод add 10000 раз. Реализация с использованием анонимных методов занимает намного меньше времени, чем другие. Зачем? Это потому, что JITter содержит анонимные методы?

delegate int ADD( int i1, int i2 );

private  void button1_Click( object sender, EventArgs e )
    {
        Stopwatch watch = new Stopwatch();
        watch.Reset();

        watch.Start();

        for( int i = 0 ; i < 10000 ; i++ )
        {
            add( i, i );
        }

        watch.Stop();
        Console.WriteLine("Normal Call " + watch.ElapsedTicks);

        watch.Reset();
        watch.Start();
        for( int i = 0 ; i < 10000 ; i++ )
        {
            ADD p = delegate( int n1, int n2 )
            {
                return n1 + n2;
            };

            p.Invoke( i, i );
        }

        watch.Stop();
        Console.WriteLine( watch.ElapsedTicks );

        Console.ReadLine();


    } 

    int add(int n1, int n2)
    {
        return n1 + n2;
    }
 }

Результат - в режиме выпуска - скомпилировать на x64 (пару раз нажал на кнопку действия):

Normal 1525
1275
Normal 480
477
Normal 371
370
Normal 372
371
Normal 477
479
Normal 477
477
Normal 564
702
Normal 478
476

1 Ответ

2 голосов
/ 26 февраля 2012

Я не могу подтвердить ваши результаты.

В моем тестировании «нормальная» функция работает примерно на порядок лучше, чем делегат. Вот ваш слегка измененный код, который я использовал для тестирования:

class Program {

    delegate int ADD(int i1, int i2);

    static int add(int n1, int n2) {
        return n1 + n2;
    }

    static void Main(string[] args) {

        Stopwatch watch = new Stopwatch();

        watch.Start();

        const int count = 100000;

        for (int i = 0; i < count; i++) {
            add(i, i);
        }

        watch.Stop();
        Console.WriteLine(watch.ElapsedTicks);

        ADD p = delegate(int n1, int n2) {
            return n1 + n2;
        };

        watch.Reset();
        watch.Start();
        for (int i = 0; i < count; i++) {
            p.Invoke(i, i);
        }

        watch.Stop();
        Console.WriteLine(watch.ElapsedTicks);

    }

}

Это печатает:

103
1321

Вы должны делать что-то, что искажает результаты.

--- РЕДАКТИРОВАТЬ ---

ОК. Я провел еще один этап тестирования, на этот раз с приложением WinForms.

  • Когда приложение WinForms скомпилировано как 'x86', результаты совпадают с указанным выше консольным приложением (функция работает быстрее, чем делегат).
  • Когда WinForms компилируется как «x64», функция резко замедляется, примерно до уровня делегата.
  • Когда функция установлена ​​на static, она снова ускоряется (в сборке WinForms x64).
  • Вышеуказанное консольное приложение никогда не замедляется, даже в сборке «x64» и даже когда функция не является статичной.

Все было измерено вне отладчика в конфигурации выпуска.

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