beforefieldinitの逆襲

ちょっと昔のネタですが
http://d.hatena.ne.jp/akiramei/20051125/p1

静的コンストラクタを書くとbeforefieldinitが付かないので望み通りの動作になります。

このときは、Singletonパターンの定石として紹介しましたが、世の中うまい話ばかりでは・・・
以下のコードを見てください。ClassとClassWithStaticConstructorの2つのクラスがあります。違いは静的コンストラクタがあるか無いかです。

using System;

class Class
{
    static int number = 42;
    public static int Number
    {
        get { return number; }
    }
}

class ClassWithStaticConstructor
{
    static int number;
    public static int Number
    {
        get { return number; }
    }

    static ClassWithStaticConstructor()
    {
        number = 42;
    }
}

class Program
{
    const int LOOP = 100000000;
    static void Main(string[] args)
    {
        DateTime t0;

        t0 = DateTime.Now;
        for (int i = 0; i < LOOP; ++i)
        {
            int n = Class.Number;
        }
        Console.WriteLine(DateTime.Now.Subtract(t0));
        
        t0 = DateTime.Now;
        for (int i = 0; i < LOOP; ++i)
        {
            int n = ClassWithStaticConstructor.Number;
        }
        Console.WriteLine(DateTime.Now.Subtract(t0));
    }
}

/* 結果
00:00:00.0468750
00:00:00.4843750
 */

ベンチマークを取ると何と10倍くらい差があります。使用する寸前までインスタンス化を遅延させるコストがゼロなわけは無かったということでした。(^^;

まぁ、業務系のアプリで問題にはならないと思いますが、ゲームやグラフィックス系なら、意識しておいて損は無いかも知れませんね。