2010-06-08 32 views
3

我想比較部分byte[]高效 - 所以我明白memcmp()應該使用。如何在字節[](帶偏移量)的兩部分上調用memcmp()?

我知道我可以使用的PInvoke調用memcmp() - Comparing two byte arrays in .NET

但是,我想比較byte[]只有部分 - 使用膠版,並沒有memcmp()與偏移,因爲它使用指針。

int CompareBuffers(byte[] buffer1, int offset1, byte[] buffer2, int offset2, int count) 
{ 
    // Somehow call memcmp(&buffer1+offset1, &buffer2+offset2, count) 
} 

我應該使用C++/CLI來做到這一點嗎?

我應該在IntPtr中使用PInvoke嗎?怎麼樣?

謝謝。

+1

爲什麼你認爲'memcmp'會比C#相當於更有效率? – jalf 2010-06-08 20:00:25

+0

與memcmp()等效的.NET是什麼?我不想自己寫這篇文章,因爲它要麼效率低下,要麼是錯誤的。 – brickner 2010-06-08 20:07:32

+0

閱讀此主題有關http://www.codeproject.com/Messages/863856/Re-memcmp-in-Csharp.aspx – lsalamon 2010-06-08 20:17:22

回答

5

C++/CLI肯定會是最乾淨的,但如果您還沒有使用C++/CLI,那麼很難證明您將C++/CLI添加到您的項目中。

Marshal.UnsafeAddrOfPinnedArrayElement(array,offset)?

2

不需要在C++/CLI中進行P/Invoke。使用pin_ptr <>來固定陣列。這會得到一個字節*,只需添加偏移量即可。

+0

我知道。所以你建議使用C++/CLI調用memcpy()而不是PInvoke? – brickner 2010-06-08 20:38:52

+0

呃,你有什麼其他的想法? – 2010-06-08 20:48:44

+1

PInvoke,就像我看到的許多參考文獻一樣,但沒有偏移功能。或者只是一些不安全的代碼? – brickner 2010-06-08 20:51:36

2

不管你做什麼,你都應該檢查offset/count值對於給定的字節數組是有效的。這樣做後,我不明白在C#中執行for循環會比P /調用Win32方法慢得多。似乎在P/Invoke中會有很多開銷,它不值得。

此外,總是有不安全的C#。

與所有性能問題一樣,您應該進行自己的性能測試。但是對我來說,就像你正試圖過早優化性能一樣。

+1

優化的'memcmp'使用SIMD指令來比較每個時鐘週期16個字節(緩衝區正確對齊時)並提供緩存提示。你用C#編寫的程序不會那樣做。對於較小的長度,p/invoke開銷太多。但更大的緩衝區大小真的從調用優化的本地代碼中獲勝 – 2014-12-05 16:23:19

14
[DllImport("msvcrt.dll")] 
private static extern unsafe int memcmp(byte* b1, byte* b2, int count); 

public static unsafe int CompareBuffers(byte[] buffer1, int offset1, byte[] buffer2, int offset2, int count) 
{ 
    fixed (byte* b1 = buffer1, b2 = buffer2) 
    { 
     return memcmp(b1 + offset1, b2 + offset2, count); 
    } 
} 

您可能還想添加一些參數驗證。

+1

需要添加CallingConvention = CallingConvention.Cdecl。默認值是WinApi或stdcall – zhaorufei 2013-09-10 06:49:23

0

還有一個辦法

SequenceEqual從System.Linq的

byte[] ByteArray1 = null; 
byte[] ByteArray2 = null; 

ByteArray1 = MyFunct1(); 
ByteArray2 = MyFunct2(); 

if (ByteArray1.SequenceEqual<byte>(ByteArray2)) 
{ 
    MessageBox.Show("Same"); 
} 
else 
{ 
    MessageBox.Show("Not Equal"); 
} 
+0

此解決方案非常慢。 – SubqueryCrunch 2017-08-10 07:00:50

相關問題