今回は、C#でなんとなくポインタを使ってみることにする。

ポインタを使うと何がうれしいかを考えてみると、・・・やっぱり速度なのかな?

ということで、

  • 配列そのまま
  • Enumeratorを使う
  • ポインタを使う

の3つで速度検証してみた。

ソース

using System;
using System.Collections.Generic;
using System.Diagnostics;namespace ConsoleApplication1
{
    class IndexExecution
    {
        static public long SumArrary(int[] aArray)
        {
            long tSum = 0;
            for (int i = 0; i < aArray.Length; i++)
            {
                tSum += aArray[i];
            }
            return tSum;
           
        }
    }

    class EnumerableExecution
    {
        static public long SumArrary(int[] aArray)
        {
            long tSum = 0;
            foreach( int tBuffer in aArray)
            {
                tSum += tBuffer;
            }
            return tSum;
        }
    }

    unsafe class PointerExecution
    {
        static public long SumArrary(int[] aArray)
        {
            long tSum = 0;
            fixed (int* tPointer = &aArray[0])
            {
                int* ptr = tPointer;
                for (int i = 0; i < aArray.Length; i++)
                {
                    tSum += *ptr++;
                }
            }
            return tSum;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            DateTime tTime;

            int[] tIntArray = new int[5000000];
            for (int i = 0; i < tIntArray.Length; i++)
            {
                tIntArray[i] = i;
            }

            tTime = DateTime.Now;
            Console.WriteLine("Index参照");
            Console.WriteLine("実行結果 = " + IndexExecution.SumArrary(tIntArray));
            Console.WriteLine("所要時間 = " + (DateTime.Now - tTime));

            tTime = DateTime.Now;
            Console.WriteLine("Enum参照");
            Console.WriteLine("実行結果 = " + EnumerableExecution.SumArrary(tIntArray));
            Console.WriteLine("所要時間 = " + (DateTime.Now - tTime));

            tTime = DateTime.Now;
            Console.WriteLine("ポインタ参照");
            Console.WriteLine("実行結果 = " + PointerExecution.SumArrary(tIntArray));
            Console.WriteLine("所要時間 = " + (DateTime.Now - tTime));

            Console.WriteLine("何かキーを押してください。");
            Console.ReadKey();
        }
    }
}

出力結果

Index参照
実行結果 = 12499997500000
所要時間 = 00:00:00.1406250
Enum参照
実行結果 = 12499997500000
所要時間 = 00:00:00.0312500
ポインタ参照
実行結果 = 12499997500000
所要時間 = 00:00:00.0312500

Index参照が遅いのは当然として、Enumeratorとポインタは同じか。なるほど。

速度が変わらないとすると、ポインタを使うメリットは・・・戻れるとか?

まあ、なにがうれしいかは次の課題として、今回はこんなとこで。

カテゴリー: 技術情報

2件のコメント

squld · 2007-05-21 15:06

速度は変わらないわ、unsafeになるわでろくな事がないッスね。
ポインタで繋がってるようなデータ構造でもない限り使わないのがよさげ。C/C++のプログラムと通信するためにどうしても欲しがったのかなぁ。

struct型の引数にrefやポインタ使えば、メモリ確保&コピーが省略されて、だいぶ速度改善しそう。とは言え、ポインタ使うよりref指定した方が良いよねぇ。

koreyasu · 2007-05-23 00:32

ほぅ、配列の場合、Enumeratorの方がIndex参照の方が早いのか。
これは勉強になったw

現在コメントは受け付けていません。