1. 程式人生 > 其它 >C#unsafe指標與C++指標

C#unsafe指標與C++指標

今天閒來無事,研究起C#的Unsafe程式碼,很好奇為什麼在操作影象陣列的時候要用指標,明明c#也提供了類似p[i]這樣的寫法。下面說說我的看法,歡迎討論

 

 

 

 

下面先介紹C#的

C#的的陣列時引用型別,繼承至Array類(因此才有Length等屬性),所以他是一般情況下是分配在堆記憶體中的。

比如下面程式碼中,0到9是儲存在堆中的,但array是定義在棧中的。

var array =new int[10]{0,1,2,3,4,5,6,7,8,9};

因此,C#中使用array[i]這樣的程式碼會先從棧中讀取地址,然後再在堆中訪問資料。

 

而使用Unsafe程式碼採用指標,可以直接訪問堆中的資料,只需要一次。

 

下面是測試程式碼,很簡單。就是定義了10000*10000的byte陣列,進行遍歷看看消耗時間。

 

  static void Main(string[] args)
        {
            NormalMethod();
            UnsafeMethod();
            Console.ReadLine();
        }

        public static void NormalMethod()
        {
            byte[] bytes = new byte[10000 * 10000];
            var
t1 = DateTime.Now; for (int i = 0; i < bytes.Length; i++) { bytes[i] = 9; } var t2 = DateTime.Now; Console.WriteLine((t2 - t1).ToString()) ; } public static unsafe void UnsafeMethod() {
var bytes = new byte[10000 * 10000]; var t1 = DateTime.Now; fixed (byte* p = bytes) { for (int i = 0; i < bytes.Length; i++) { p[i] = 9; } }; var t2 = DateTime.Now; Console.WriteLine((t2 - t1).ToString()); }

可以看到Unsafe指標的確快一點

 

 

 

 

 

再看看C++版本的:

    unsigned char *bytes = new unsigned char[10000*10000];
    clock_t start = clock();
    for (size_t i = 0; i < 10000*10000; i++)
    {
        bytes[i] = 3;
    }
    clock_t end = clock();
    std::cout << double(end - start) / CLOCKS_PER_SEC;

 

 

 

C++處理速度則快的多,怪不得對於效能要求高的一般用C++實現