CLR 2.0 でのデバッグ実行

827 :デフォルトの名無しさん :2005/12/24(土) 00:19:48

  1. C#コンソールアプリの新規プロジェクトを作る
  2. 参照設定は、System, System.Drawing
  3. 以下をコピペ
    using System;
    using System.Drawing;
    class Program
    {
        static void Main(string[] args)
        {
            int w = 1000; int h = 1000;
            DateTime dt = DateTime.Now;
            Bitmap b = new Bitmap(w, h);
            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                    b.SetPixel(x, y, Color.FromArgb(x + y));
            
            TimeSpan ts = DateTime.Now - dt;
            Console.WriteLine(ts.ToString());
            Console.Read();
        }
    }
  4. 実行
    デバッグなし(Ctrl+F5) で、2.8秒
    デバッグ(F5) で49秒 、17分の1のスローダウン、遅すぎるwww

適当 Workaround だけど,デバッグなしで起動して起動後にデバッガをアタッチすればスローダウンしないみたいですな*1

using System;
using System.Drawing;
using System.Diagnostics;
class Program
{
    static void Main(string[] args)
    {
        if (!Debugger.IsAttached)
        {
            Debugger.Launch();
        }
        int w = 1000; int h = 1000;
        DateTime dt = DateTime.Now;
        Bitmap b = new Bitmap(w, h);
        for (int y = 0; y < h; y++)
            for (int x = 0; x < w; x++)
                b.SetPixel(x, y, Color.FromArgb(x + y));
        
        TimeSpan ts = DateTime.Now - dt;
        Console.WriteLine(ts.ToString());
        Console.Read();
    }
}

ちょっと気になったので,VTune 7.1 でサンプリングデータを採ってみました.デバッガから起動した場合は,そうで無い場合に比べて著しく mscorwks.dll の CPU 占有率が上がっていて,最も CPU 占有率が高かったのは LogHelp_TerminateOnAssert という関数でした.以下にサンプリング結果を Excel に落としたものを置いておきます*2
http://www.dwahan.net/nyaruru/hatena/debugslowdown.xls
今のところこれ以上突っ込んで調べる必要性が無いため放置気味ですが,興味がある方はまあどうぞという感じで.
しかしまあ C++ のコードをデバッグするために色々最適化オプションを解除すると,とんでもなくスローダウンした状況でデバッグする羽目になる,なんてのは何度も経験してきましたし,この程度ではあんまりびっくりってことは無いですかね.
(追記) これかな? FDBK41388 とりあえず Workaround 入れておくか.

*1:折角 Windows XP 以降は例の制限(id:NyaRuRu:20050406#p2)が無くなってアタッチとデタッチを繰り返すデバッグ方法が使い放題なわけですし

*2:余談ですけど,実際の SetPixel の処理よりも,GdipGetImageHeight とGdipGetImagePixelFormat と GdipGetImageWidth 合わせて 3 倍以上コストがかかっているってのがアレですな