2013-01-22 78 views
0

我發現了兩種方法將byte[]轉換爲結構。但我不知道這兩種方法是否有區別?誰能知道哪個更好(性能,...)?哪個編組方法比較好?

#1:

public static T ByteArrayToStructure<T>(byte[] buffer) 
{ 
    int length = buffer.Length; 
    IntPtr i = Marshal.AllocHGlobal(length); 
    Marshal.Copy(buffer, 0, i, length); 
    T result = (T)Marshal.PtrToStructure(i, typeof(T)); 
    Marshal.FreeHGlobal(i); 
    return result; 
} 

#2:

public static T ByteArrayToStructure<T>(byte[] buffer) 
{ 
    GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); 
    T result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 
    handle.Free(); 
    return result; 
} 
+0

更好的是什麼條件?順便說一句,我認爲第二個不符合你的期望。你測試過它們嗎?如果是這樣,請向我們展示您用於確保方法按預期工作的代碼。 – GameScripting

+0

更好的表現(我編輯我的帖子)。你確定#2不起作用嗎? –

+0

好的。所以有一些差異。你能告訴更多嗎? –

回答

2

我使用下面的代碼爲你做一個標杆:

const int ILITERATIONS = 10000000; 

const long testValue = 8616519696198198198; 
byte[] testBytes = BitConverter.GetBytes(testValue); 

// warumup JIT 
ByteArrayToStructure1<long>(testBytes); 
ByteArrayToStructure2<long>(testBytes); 

Stopwatch stopwatch = new Stopwatch(); 
stopwatch.Start(); 

for (int i = 0; i < ILITERATIONS; i++) 
{ 
    ByteArrayToStructure1<long>(testBytes); 
} 

stopwatch.Stop(); 
Console.WriteLine("1: " + stopwatch.ElapsedMilliseconds); 

stopwatch.Reset(); 

stopwatch.Start(); 

for (int i = 0; i < ILITERATIONS; i++) 
{ 
    ByteArrayToStructure2<long>(testBytes); 
} 

stopwatch.Stop(); 
Console.WriteLine("2: " + stopwatch.ElapsedMilliseconds); 

stopwatch.Reset(); 

stopwatch.Start(); 

for (int i = 0; i < ILITERATIONS; i++) 
{ 
    BitConverter.ToInt64(testBytes, 0); 
} 

stopwatch.Stop(); 
Console.WriteLine("3: " + stopwatch.ElapsedMilliseconds); 

Console.ReadLine(); 

我來以下結果:

1: 2927 
2: 2803 
3: 51 
+0

附註:確保有熱身呼叫排除JIT,看看你是否實際調用2種不同的方法... –

+0

@AlexeiLevenkov謝謝你的建議,更新了我的回答:) – GameScripting