Debug.Print slow when debugger is not attached

I just noticed this. Debug.Print significantly slows down the code when the debugger is not attached. Attach the debugger and everything returns to normal.

On my Spider with Latest Framework 4.2, the below contrived example demonstrates the problem

Notice: I put the Debug.Print in a loop just to exaggerate the problem. With the debugger attached the elapsed time is very close to the expected 1000ms, but as soon as the debugger detaches the time jumps to around 5000ms. Attach the debugger and the queued timer ticks fire in quick succession to catchup and then everything returns to normal hovering around 1000ms.

Is this expected to have such a dramatic slowdown 4 seconds to execute 10 Debug.Print statements?


using Microsoft.SPOT;
using GT = Gadgeteer;
using System;

namespace Spider42Test
{
  public partial class Program
  {
    GT.Timer _timer = new GT.Timer(1000);
    Font _font;
    DateTime _lastTime;

    void ProgramStarted()
    {
      _font = Resources.GetFont(Resources.FontResources.NinaB);
      _timer.Tick += new GT.Timer.TickEventHandler(_timer_Tick);
      _lastTime = DateTime.Now;
      _timer.Start();
      
      Debug.Print("Program Started");
    }

    void _timer_Tick(GT.Timer timer)
    {
      TimeSpan period = DateTime.Now - _lastTime;
      _lastTime = DateTime.Now;
      long elapsedSeconds = period.Ticks / TimeSpan.TicksPerMillisecond;

      display_T35.SimpleGraphics.ClearNoRedraw();
      display_T35.SimpleGraphics.DisplayText(elapsedSeconds.ToString(), _font, GT.Color.Red, 0, 0);
      for (int i = 0; i < 10; i++)
      {
        Debug.Print(elapsedSeconds.ToString());
      }
    }
  }
}

I think so. With no receiving end some timeouts start to kick in.

@ taylorza - To speed up execution of release code, you can either create your own Debug.Print function that wraps the call to Debug.Print with

#if DEBUG

Or, you can wrap each Debug.Print statement with it, and it will not be compiled with the rest of your code.

@ James - thanks for the advice, my issue is not with how to optimize this it is with the fact that the overhead is so high. I was wondering if this is new to 4.2 or has this always been the case.

@ taylorza - I am not positive if it has always been like this, however, there are multiple factors that could contribute to the slowdown aside from @ Architect 's time-out suggestion (which is also true). For example, you can take a look at MFDeploy 4.1 version, Ping replies are almost instantaneous where as in 4.2 QFE2 there is a noticeable delay in the device’s response. This could be caused by the WinUSB drivers themselves because WinUSB, in theory, is interpreted drivers as opposed to native running drivers. This interpretation can slow things down a little however this is what directly protects you from encountering the BSOD when you reset the device with a debugger attached.

I would compare it with 4.1 and on multiple devices then report to Microsoft.

WinUSB isn’t interpreted, it’s user-mode. These concepts are VERY VERY different, and while having a user-mode driver makes it much safer (user-mode code can’t cause a BSOD), it shouldn’t make it much slower (user-mode code is still native code, just running in user mode instead of kernel mode).