技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

.NET のGenericパフォーマンス比較してみる

C#3.5 以上のコンパイラだと、2.0対象でもいろいろシンタックスシュガー使えるので楽ね。
コンパイル後の中間コードに、generic 専用構文があるから、変換コストゼロで使える。
逆にJavaの場合、コンパイラが暗黙でキャストするだけだから、変換コストがかかる。

コード的に見れば整理するためにも十分必要なんだけどね。
Flex とかこの辺無いから結構困る。

Generic なデータコンテナ。

class GenericList<ContentsType>
{
    public ContentsType contents { get; set; }
    public GenericList<ContentsType> nextNode { get; set; }

    public static GenericList<T> setNextNode<T>(
        GenericList<T> connectNode,
        T contents)
    {
        GenericList<T> nextNode = new GenericList<T>();
        nextNode.contents = contents;

        connectNode.nextNode = nextNode;
        return nextNode;
    }
}

非Genericなコンテナ

class NonGenericList
{
    public Object contains { get; set; }
    public NonGenericList nextNode { get; set; }

    public static NonGenericList setNextNode(
        NonGenericList connectNode,
        Object contents)
    {
        NonGenericList nextNode = new NonGenericList() {
            contains = contents
        };

        connectNode.nextNode = nextNode;
        return nextNode;
    }
}

実行速度比較

static void Main(string[] args)
{
    GenericList<string> genericList = new GenericList<string>();
    NonGenericList nonGenericList = new NonGenericList();

    NonGenericList currentNode = nonGenericList;
    GenericList<string> currentGenericList = genericList;

    string sampleText = "SampleText";

    for (int i = 0; i < 10000; i++)
    {
        currentNode = NonGenericList.setNextNode(
            currentNode, sampleText);
        genericList = GenericList<string>.setNextNode<string>(
            currentGenericList, sampleText);
    }

    currentNode = nonGenericList;
    long start = DateTime.Now.Ticks;
    while (currentNode != null)
    {
        string value = (string)currentNode.contains;
        currentNode = currentNode.nextNode;
    }
    long stop = DateTime.Now.Ticks;

    Console.WriteLine("Non generic list insert 10000 : " + (stop - start).ToString());

    // generic の場合
    currentGenericList = genericList;
    start = DateTime.Now.Ticks;

    // currentNode で書いてた(修正:1/20)
    while (currentGenericList != null)
    {
        string value = currentGenericList.contents;
        currentGenericList = currentGenericList.nextNode;
    }
    stop = DateTime.Now.Ticks;

    Console.WriteLine("Generic list insert 10000 : " + (stop - start).ToString());

    Console.ReadLine();
}

結果

Non generic list insert 10000 : 10001
Generic list insert 10000 : 10000

キャストにかかるコスト差ってこんなにあったっけ?
んーこの数ではそんなに変わらない、、、。