2016年10月6日木曜日

【C#】Debug版とRelease版の速度差

C++では特にstlやboostあたりを使うと、Debug版とRelease版の間で速度差が生まれる。C#では速度がどの程度になるか試してみる。いずれもビルド後にエクスプローラからexeファイルを実行。

◆結論:思った程、速度差は無いが、Release版の方が早い。ただし、Release版はデフォルトから設定を変更している(後述)。下記ではListクラスを試したが、別のクラスではもっと開きがあるかも。

【1】Listの末尾に1000万回文字列を追加
■コード①
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Performance
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            var list = new List<string>();
            for (int i = 0; i < 1000 * 1000 * 10; i++)
                list.Add(i + "");

            sw.Stop();

            Console.WriteLine("処理時間:" + sw.Elapsed);
            Console.ReadKey();
        }
    }
}


■結果①
Release版1回目:4.95秒
Release版2回目:4.98秒
Debug版1回目:4.97秒
Debug版2回目:4.97秒

【2】Listに100万回文字列を追加し、全て配列外

■コード②
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Performance
{
    class Program
    {
        static void Main(string[] args)
        {
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            var list = new List<string>();
            for (int i = 0; i < 1000 * 1000; i++)
                try { list.Insert(i + 1, i + ""); }
                catch { }   // 例外無視は、絶対に真似しない事。

            sw.Stop();

            Console.WriteLine("処理時間:" + sw.Elapsed);
            Console.ReadKey();
        }
    }
}


■結果②
Release版1回目:13.77秒
Release版2回目:13.40秒
Debug版1回目:13.55秒
Debug版2回目:13.50秒

【3】Listの10億回シーケンシャルリード
■コード③
using System;
using System.Collections.Generic;
using System.Linq;

namespace Performance
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = Enumerable.Range(0, 1000 * 1000 * 100).ToList();  // varはList<int>

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            long sum = 0;
            foreach (var tmp in Enumerable.Range(0, 10)) // ↑のRange()で10億指定するとToList()でOutOfMemoryとなるため、仕方なく2重ループ
                foreach (var elem in list)
                    sum += elem;
                
            sw.Stop();

            Console.WriteLine("処理時間:" + sw.Elapsed);
            Console.WriteLine("sum:" + sum);
            Console.ReadKey();
        }
    }
}



■結果③
Release版1回目:5.49秒
Release版2回目:5.13秒
Debug版1回目:7.84秒
Debug版2回目:7.81秒

【4】Listの10億回インデックスリード
■コード④
using System;
using System.Collections.Generic;
using System.Linq;

namespace Performance
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = Enumerable.Range(0, 1000 * 1000 * 100).ToList();  // varはList<int>

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            long sum = 0;
            foreach (var tmp in Enumerable.Range(0, 10)) // ↑のRange()で10億指定するとToList()でOutOfMemoryとなるため、仕方なく2重ループ
                foreach (var elem in list)
                    sum += list[elem];
                
            sw.Stop();

            Console.WriteLine("処理時間:" + sw.Elapsed);
            Console.WriteLine("sum:" + sum);
            Console.ReadKey();
        }
    }
}

■結果④
Release版1回目:6.77秒
Release版2回目:7.26秒
Debug版1回目:12.80秒
Debug版2回目:13.21秒


◆環境
■VMware WorkStation10上の仮想マシン
・CPU:2
・メモリ:2GB
・OS:Windows7
・Visual Studio 2015 Community

■ホストPCの性能(参考)
・CPU:Intel Core i5-4250U
メモリ:8GB
ドライブ:SSD(Plextor PX-512M3P)
・OS:Windows10

◆デバッグ版とリリース版の設定差異
・デバッグ版は新規プロジェクト作成から変更なし。
・リリース版は新規プロジェクト作成からpdb未生成、ホスティングプロセス無効の計2箇所のみ変更。

・Debug版(デバッグ情報有り)


・Release版(デバッグ情報無し)


・Debug版(ホスティングプロセス有効)


・Release版(ホスティングプロセス無効)


ちなみに、【2】に関しては、VisualStudio上で実行するとブレークポイントが無くてもRelease版の方が早い。


0 件のコメント:

コメントを投稿