C#unsafe指標與C++指標
阿新 • • 發佈:2022-03-20
今天閒來無事,研究起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]; vart1 = 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++實現