Почему использование операторов Debug делает код действительно медленным? - PullRequest
1 голос
/ 17 марта 2011

У меня есть этот цикл

        // go through each alumni
        foreach (esDL.Alumni currAlumni in allAlumnis)
        {
            ... loop logic

        }

Этот запуск выполняется почти мгновенно.

Когда я добавляю оператор трассировки или отладки, как ...

        foreach (esDL.Alumni currAlumni in allAlumnis)
        {
            ... same loop logic

            Trace.WriteLine("hi");
            Trace.Indent();
            Trace.WriteLine("written");

        }

Это значительно замедляет ход событий. Оба для трассировки или отладки

Почему это? Есть ли способ предотвратить это?

У меня подключен только прослушиватель по умолчанию.

РЕДАКТИРОВАТЬ - после дополнительного тестирования я обнаружил, что Trace.Indent делает его намного, намного медленнее. Но наличие только WriteLine там все еще существенно снижает производительность. Что не так с методом Indent?

Ответы [ 2 ]

1 голос
/ 17 марта 2011

Я предполагаю, что вы вызываете Trace.Indent () для каждой строки, не вызывая Trace.Unindent (), что приводит к тому, что уровень отступа продолжает расти.

Предполагается, что у вас есть 2000 строк для обработки, и в настоящее время вы обрабатываете 1000-ю строку, что делает IndentLevel 1000. Предполагается, что отступ представлен символом Unicode '\ t' (предполагается, что UTF-16, что составляет 2 байта на символ)).Затем, в этот момент, чтобы создать трассировку отладки, около 2 КБ памяти должно быть выделено для этой конкретной трассировки в итерации.Выделение такого объема памяти не является дешевой операцией, и вы фактически увеличиваете размер записи трассировки в каждой итерации.

Кроме того, мне не ясно, когда память будет освобождена сборщиком мусора.Другими словами, когда основная инфраструктура отладки будет выполняться с использованием памяти.Поскольку вы создаете длинные записи трассировки довольно часто, скорее всего, она исчерпает кучу Gen1.Когда включается сборщик мусора и некоторые строки трассировки не обрабатываются инфраструктурой отладки, они также переходят в кучу Gen2.Это увеличит размер рабочего набора вашего процесса, что снова может замедлить ваш процесс.

Вы можете проверить счетчики производительности .NET для своего приложения.Я бы проверил Размер кучи Gen1, Gen2, Gen3, общий размер кучи, # Gen1, Gen2, Gen3 сборки мусора.Чем выше сборка мусора Gen в вашем приложении, тем медленнее будет и ваше приложение.

Это всего лишь мое приблизительное предположение.

1 голос
/ 17 марта 2011

Любой объем отладки может замедлить вашу программу даже до такой степени, что она будет работать на одну десятую скорости.Он должен отправлять сообщения как вашим слушателям (у вас их нет), так и прослушивателю по умолчанию, который пересылает его как Debugger.Log, так и Win32 OutputDebugString - неудивительно, что он немного замедляется: -)

Относительно того, почему отступ может иметь большой эффект, вы фактически не отступаете где-то в этом цикле?Если это не так, и у вас есть 2000 элементов (согласно вашему комментарию в другом месте), это будет довольно много места в начале каждой строки, когда вы приближаетесь к концу (в среднем 1000 отступов на строку, вероятно,быть проблематичным).

...