.NET 2.0 против производительности распределения времени выполнения .NET 4.0

после перехода с .NET 3.5 (среда выполнения .NET 2.0) на NET 4.0 мы можем увидеть снижение производительности при выделении больших блоков памяти. Просмотрите следующий тестовый код. Это минималистичная программа тестирования, представляющая реальный сценарий, который мы используем. Может ли кто-нибудь объяснить резкую разницу между средой выполнения .NET 2.0 и 4.0, которая намного медленнее? Действия по воспроизведению:

  1. Импортируйте код в консольное приложение C #.
  2. Установите целевую платформу на x64.
  3. Нацельтесь на .NET 3.5 и сделайте сборку Release.
  4. Запустите EXE (НЕ запускайте из IDE!) И введите "test" в консоль.
  5. Ждите результатов.
  6. Повторите для .NET 4.0.

Спасибо.

Алекс

    class Program {

    static DateTime firstdate, lastdate;

    const int CHUNKSIZE =  10 * 1024 * 1024; //  10 MB.
    const int TRIALS = 10000;

    static void startmeasure() {

        firstdate = DateTime.Now;

    }

    static void stopmeasure() {

        lastdate = DateTime.Now;

        var duration = lastdate.Subtract(firstdate);

        Console.WriteLine("Test duration:" + duration.TotalSeconds.ToString());

    }

    static void Main(string[] args) {

        string input;

        do {

            input = Console.ReadLine();

            switch (input) {

                case "test":

                    handletest();

                    break;

            }

        } while (input != "exit");

    }

    static void handletest() {

        startmeasure();

        byte[] data;

        for (int i = 0; i < TRIALS; i++) {

            data = getdata(CHUNKSIZE);

        }

        stopmeasure();

    }

    static byte[] getdata(int size) {

        return new byte[size];

    }

}

person Alex    schedule 17.10.2017    source источник
comment
Ваш код было бы значительно легче читать, если бы у вас не было так много пустых строк. Пробелы полезны, но не после каждой строки ... (Я также посоветовал бы вам соблюдать соответствующие соглашения об именах даже для одноразового кода - это упрощает чтение для всех.)   -  person Jon Skeet    schedule 17.10.2017
comment
Это побочный эффект RyuJIT, переписанного джиттера x64, который впервые появился в .NET 4.6. У старого джиттера был гораздо более агрессивный оптимизатор, функция, которая умела превращаться в ошибку. Старый оптимизатор полностью удаляет вызов getdata (), поскольку его возвращаемое значение никогда не используется. Конечно, большая разница. То, что вы действительно обнаружили проблему с перфомансом, маловероятно, никто на самом деле не пишет такой код. Обязательно подумайте об использовании профилировщика для реального кода, чтобы вы могли сузить дорогостоящую его часть.   -  person Hans Passant    schedule 17.10.2017


Ответы (1)


Как указал Ханс, ответ заключается в различных способах оптимизации быстрого выделения памяти и раннего освобождения объектов в .NET 2 и 4. То, что .NET 4 работает медленнее в этом тестовом коде, не означает, что его производительность ниже для реальных приложений, так что это просто особая ситуация.

A.

person Alex    schedule 18.10.2017