Список <string>декларации различий в скорости в режиме отладки - PullRequest
0 голосов
/ 01 февраля 2019

Я создал небольшое консольное приложение для тестирования на C # с помощью класса System.Diagnostics.StopWatch, чтобы узнать, сколько времени занимает 3 метода:

Как запустить тест:

public void Run()
{
    Stopwatch sw = new Stopwatch();

    sw.Start();
    InitDirectly();
    sw.Stop();
    Console.WriteLine($"InitDirectly: {sw.Elapsed.TotalMilliseconds}ms");

    sw.Reset();

    sw.Start();
    InitWithAdd();
    sw.Stop();
    Console.WriteLine($"InitWithAdd: {sw.Elapsed.TotalMilliseconds}ms");

    sw.Reset();

    sw.Start();
    InitWithForLoop();
    sw.Stop();
    Console.WriteLine($"InitWithForLoop: {sw.Elapsed.TotalMilliseconds}ms");
}

Метод 1:

private void InitListDirectly()
{
    var list = new List<string>() {
        "string",
        "string",
        "string",
        //... up to a 100th entry
    };
}

Метод 2:

private void InitListViaAdd()
{
    var list = new List<string>();
    list.Add("string");
    list.Add("string");
    list.Add("string");
    //... up to a 100th entry
}

Метод 3:

private void InitListViaForLoop() {
    var list = new List<string>();
    for (int i = 0; i < 100; i++) {
        list.Add("string");
    }
}

Теперь запустите секундомер перед способом 1, затем остановите.То же самое для метода 2.

  1. Метод 1 занял ~ 0,800 мс
  2. Метод 2 занял ~ 1 000 мс
  3. Метод 3 занял ~ 0,120 мс

Теперь я удивлен, что цикл for (метод 3) намного быстрее.Я ожидал, что метод 1 будет самым быстрым, поскольку другие два метода должны вызывать «Add (string)», а третий должен создать цикл for.

Почему метод 3 намного быстрее?Это из-за какой-то компиляции?Понимает ли он, что оператор внутри цикла for будет одинаковым для всех его итераций?

EDIT: я работал в режиме отладки.

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Потребовалась целая миллисекунда, чтобы добавить 100 строк к List<>?Это как от 2 до 4 миллионов тактов !!Это безумно, и гораздо дольше, чем даже режим отладки может объяснить фактический запуск кода.

Поскольку вы вызываете каждую функцию ровно один раз, может быть, это включает время для JIT-компиляции функции?

Короткая функция с циклом может легко JIT в машинный код намного быстрее, чем более крупные функции, даже в режиме отладки, потому что JIT-компилятору гораздо меньше байт-кода для работы.

0 голосов
/ 01 февраля 2019

Это не ответ на ваш вопрос, но, возможно, если вы используете BenchmarkDotNet для тестов, ваш вопрос будет другим.

...