我知道不安全的代碼更適合訪問像Windows API之類的東西,並執行不安全的類型轉換,而不是編寫更高性能的代碼,但我想問問你是否注意到任何重大的性能改進與安全的c#代碼相比,使用它的真實世界的應用程序。真正不安全的代碼性能
回答
一個很好的例子是圖像處理。通過使用指向字節的指針(這需要不安全的代碼)來修改像素速度要快很多。
實施例:http://www.gutgames.com/post/Using-Unsafe-Code-for-Faster-Image-Manipulation.aspx
如此說來,對於大多數情況,差異不會像明顯。因此,在使用不安全的代碼之前,請對應用程序進行配置以查看性能瓶頸的位置,並測試不安全的代碼是否是真正的解決方案,以使其更快。
安全圖像處理也可以相當快。特別是如果您的算法可以寫入以消除邊界檢查。我只使用不安全的代碼將數據從位圖複製到數組中並返回。如果你使用byte [],你甚至可以避免使用'Marshal'函數。 – CodesInChaos 2011-03-21 08:40:37
@ Botz3000:這是一個很好的鏈接(期待閱讀網站的其餘部分),但結論是不健全的。使用'GetPixel'和'SetPixel' _is_真的很慢,但使用'int []'或多或少像使用沒有缺點的指針一樣快。 – 2012-07-10 09:01:06
@CodeInChaos:我必須同意。我得出的結論是唯一受益的方面是複製位圖數據。儘管如此,還沒有嘗試過使用'元帥'。 – 2012-07-10 09:02:28
正如其他帖子所述,您可以使用可以在非常專業的環境中使用不安全的代碼,以獲得顯着的性能提升。其中一種情況是迭代數組值類型。使用不安全的指針運算比使用for循環/索引的通常模式快得多..
struct Foo
{
int a = 1;
int b = 2;
int c = 0;
}
Foo[] fooArray = new Foo[100000];
fixed (Foo* foo = fooArray) // foo now points to the first element in the array...
{
var remaining = fooArray.length;
while (remaining-- > 0)
{
foo->c = foo->a + foo->b;
foo++; // foo now points to the next element in the array...
}
}
這裏的主要好處是,我們已經削減了數組索引完全檢查..
雖然很高性能,這種代碼很難處理,可能是相當危險的(不安全),並且破壞了一些基本的準則(可變結構)。但是,確實有一些場景中,這是合適的......
這種代碼的另一個重大缺陷是C#程序員中很大一部分人不瞭解它或其含義。如果你在一個團隊工作,採用KISS原則... – MattDavey 2011-03-21 09:12:02
你確定這個特定的例子更快嗎? Sun的JVM使用指針算法使這種類型的代碼(Java或Scala)幾乎與C++一樣快;我很驚訝C#實現不會這麼做。 – 2011-03-21 16:16:45
這個特殊的例子,不,因爲編譯器可以確定** i **永遠不會超出數組的邊界,因此跳過數組邊界檢查。但原則依然存在。在我的具體情況下,我有一個使用數組實現的環形緩衝區,以及一個迭代它的獨立Iterator對象。在這種情況下,編譯器無法進行此優化.. – MattDavey 2011-03-21 16:58:52
一些性能測量
的性能優勢並不像你想象的那麼大。
我做了一些正常的託管數組訪問與C#中的不安全指針的性能測量。從Visual Studio 2010,.NET 4之外運行構建
結果,使用 任何CPU |發佈基於以下PC規格:基於x64的PC,1個四核處理器。 Intel64家族6型號23步進10 GenuineIntel〜2833Mhz。
Linear array access 00:00:07.1053664 for Normal 00:00:07.1197401 for Unsafe *(p + i) Linear array access - with pointer increment 00:00:07.1174493 for Normal 00:00:10.0015947 for Unsafe (*p++) Random array access 00:00:42.5559436 for Normal 00:00:40.5632554 for Unsafe Random array access using Parallel.For(), with 4 processors 00:00:10.6896303 for Normal 00:00:10.1858376 for Unsafe
注意,不安全*(p++)
成語居然跑慢。我猜想這打破了一個編譯器優化,它結合了循環變量和安全版本中的(編譯器生成的)指針訪問。
源代碼可在github。
嗯,我建議閱讀這個博客員額:MSDN blogs: Array Bounds Check Elimination in the CLR
這澄清越界檢查如何在C#中進行。而且,Thomas Bratts測試對我來說似乎沒用(看代碼),因爲JIT無論如何都會在他的「保存」循環中刪除綁定檢查。
你可以在這裏總結這篇文章。如果鏈接變黑,你的回答不會很有幫助。 – ChrisF 2012-09-30 20:32:58
您已經錯過了測試的要點 - 它們不會顯示邊界檢查與不安全的效果。他們要證明邊界檢查經常被優化,而且在這些情況下不安全的代價可能是不值得的。 – 2013-03-25 15:57:48
我對視頻操作代碼使用不安全的代碼。 在這樣的代碼中,您希望它在沒有對值進行內部檢查的情況下儘可能快地運行。沒有不安全的屬性,我可能無法跟上30fps或60 fps的視頻流。 (取決於使用的相機)。
但是由於速度它被代碼圖形的人廣泛使用。
- 1. PHP的代碼安全性
- 2. 源代碼公開後的安全性
- 3. 此cURL代碼的安全性
- 4. .NET Thread不安全代碼
- 5. 我怎樣才能提高這個php代碼的安全性?
- 6. AngularJS - 爲什麼不能取代:真正的templateUrl屬性?
- 7. 爲什麼我的不安全代碼塊比我的安全代碼慢?
- 8. 「不安全代碼只能出現如果與/不安全編譯」
- 9. 爲什麼不編譯這個代碼?這真的是不安全的?
- 10. Spring安全性能
- 11. PHP代碼安全
- 12. Java代碼,安全
- 13. 不安全的代碼說明
- 14. Silverlight和不安全的代碼
- 15. C中的不安全代碼#
- 16. 憲兵不安全的代碼檢測
- 17. IntPtr和避免不安全的代碼
- 18. 如何在安全比賽中使用不安全的代碼?
- 19. 什麼是C/C++中的「安全」和「不安全」代碼?
- 20. 使不安全的代碼在C#安全
- 21. REST項目不能正常工作的彈簧安全性
- 22. .NET中的代碼安全
- 23. Mysqli的安全代碼
- 24. 哪些ASP.NET命令可能導致不安全的代碼?
- 25. 代碼訪問安全性正在阻止PInvoking安裝API調用
- 26. 使用代碼訪問安全性,而不GAC
- 27. PHP編譯器編碼的代碼安全性如何?
- 28. 安全索引裏面不安全代碼
- 29. .NET Micro Framework不安全代碼
- 30. 如何編譯C#不安全代碼
P/Invoke與'unsafe'不太一樣......我不確定推理如下...另外:你是否測量了一下,看看你是否在做一些有用的事情? – 2011-03-21 07:21:02
既不安全也不安全的應該是事實上更高性能的。總體性能取決於您在代碼中實現的算法。 – zerkms 2011-03-21 07:22:11
我現在沒有使用不安全的代碼。我只是想了解是否值得將代碼的關鍵部分更改爲不安全的代碼。 – Miguel 2011-03-21 07:23:49