开发者

Why does using Debug statements make code run really slow?

I have this loop

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

        }

This run almosts instanteously.

When I put in a trace or debug statement like so...

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

            Trace.WriteLine("hi");
           开发者_Go百科 Trace.Indent();
            Trace.WriteLine("written");

        }

This slows things down considerably. Both for Trace or Debug

Why is that? Is there a way to prevent this?

I have only the default listener attached.

EDIT - upon more testing I've found that Trace.Indent makes it much, much slower. But having just the WriteLine there still decreases performance substantially. What's wrong with the Indent method?


Any amount of debugging is likely to slow down your program even to the point of running at one-tenth the speed. It has to send messages both to your listeners (you don't appear to have any) and the default listener, which forwards it to both Debugger.Log and the Win32 OutputDebugString - little wonder it slows down a bit :-)

As to why the indent may be having a large effect, are you actually unindenting somewhere in that loop? If you're not, and you have 2000 items (as per your comment elsewhere), that's going to be quite a lot of space on the front of each line as you approach the end (an average of 1000 indents per line is likely to be problematic).


I am assuming you are calling Trace.Indent() for each row without calling Trace.Unindent(), which makes the indent level keeps increasing.

Supposed you have 2000 rows to process and you are currently processing 1000th row, which makes IndentLevel 1000. Supposed indent is represented by '\t' a unicode character (assuming UTF-16, which is 2 bytes per char). Then, at that point, to create a debug trace, around 2KB memory has to be allocated for that particular trace in the iteration. Allocating that size of memory is not cheap operation and you are actually increasing the size of the trace entry in each iteration.

Also, it is not clear to me when the memory will be freed by garbage collection. In other words, when the underlying debugging infrastructure will be done using the memory. Since you are creating the long trace entries quite frequently, it is likely to exhaust the Gen1 heap quite quickly. When the garbage collector kicks in and some of the trace lines are not processed by the debugging infrastructure, they will be moving to Gen2 heap as well. That will increase the working set size of your process that again may slow your process down.

You may want to check the .NET performance counters for your application. I would check Size of Gen1, Gen2, Gen3 heaps, total heap size, # of Gen1, Gen2, Gen3 garbage collections. The more higher Gen garbage collection your application does, the slower your application will be as well.

This is just my rough guess, though.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜