託管程式碼(.net)比非託管程式碼(vc++)慢嗎?
如果你用上面這個問題去問每一個人,基本上每個人都會回答,肯定會慢! 那麼他們說的是正確的嗎? 不,並不正確。 問題在於,絕大多數人認為.Net只是一個基於執行庫的框架,就像Java或者VB,或者他們甚至以為.Net使用像Java一樣的虛擬機器系統。 他們並沒考慮到程式本身,沒考慮到程式是用來幹什麼,也沒有考慮到訪問網路或者磁碟的速度因素。簡單來說,就是他們根本沒有思考!
.NET並不像那種執行庫(VB或者Java)。 它是一個經過精心構思的,並且微軟在其身上下了極大功夫的框架,以保證它的良好執行。 在這篇文章 我將給大家展示一些將需要大量運算的程式碼,並且將他編譯成託管以及非託管程式碼。 然後我將測量這兩個庫分別的表現。 你將看到, 並不會因為這是.net程式就自動要比c++程式慢,事實是,在某些情況,託管程式碼甚至比非託管程式碼更快。
題外話(我自己補充的,原文沒有提到):
.NET的執行機制,由於本人現在研究的專案跟.Net庫底層有些關係,所以多少了解一些,現在簡單給大家介紹一下。
基本上每個人都知道的是,所有.Net語言都將被編譯成為一個叫做IL彙編的中間語言。但是計算機是如何執行這個中間程式碼的,卻是很多人不知道,甚至理解錯誤了的。
JIT是.NET程式執行的重要部件之一,全稱是即時編譯器。我剛才說的誤解,就是很多人(絕對不是少數,問了很多c++程式設計師,10個有9個這種想法)都以為JIT其實就是跟Java VM差不多的東西,是一個Interpreter,在執行時讀取IL彙編程式碼,然後模擬成x86程式碼(也就是俗稱的虛擬機器)。但是事實上,.NET使用的是更為高階的技術。 .Net程式被載入入記憶體以後,當某段IL程式碼被第一次執行的時候,JIT編譯器就會將這段IL程式碼,全部編譯成原生程式碼,然後再執行。這也就是為什麼.NET程式第一次執行都啟動很慢的原因! 隨.NET庫,微軟還附帶了一個工具,可以事先將.NET程式所有的IL程式碼都編譯成原生程式碼並儲存在快取區中,這樣一來,這個程式就跟c++編譯的一模一樣了,沒有任何區別,執行時也可以脫離JIT了(這裡不要混淆了,這裡不是說可以脫離.NET庫,而是說不需要在進行即時編譯這個過程了)。所以,請不要將.NET和Java混為一談,兩個的執行效率根本不是一個等級的!
作為測試演算法,我們選中了FFT(Fast Fourier Transform),這是一個將跟時間有關係的資料(例如音樂)轉換成他應有的頻率資訊的演算法。
這個演算法有很多種,如果你用Google搜尋會發現很多,這裡我選中了Real Discrete Fourier Transform, 因為他比較簡單明瞭,比較好修改。 我將其複製了4份,分別用於測試託管的C++, C++/CLI,C#。
非託管的程式碼我只是將其函式名稱改成了fourier,並且加入了__declspec(dllexport)用來匯出。
託管的程式碼改動的要稍多些:
* 方法引數改成了託管的Array, 並且使用Array::Length來代替額外的長度引數
* 涉及到三角函式的地方都改為使用Math類下的方法
* 演算法被作為一個公開類的靜態成員匯出
然後我把託管的c++程式碼轉換成了c#,只做了極小的變化(大多數是語法上以及申明上的改動)
最後,我又將託管的c++程式碼轉換成了C++/CLI
然後我們將所有版本都分別編譯幾個不同的版本:未優化版,空間優化,速度優化.
結果:
我將這些程式分別在兩臺電腦上進行了測試,一臺是裝了.net 2.0的 XPSP2,處理器是PIII 850, 512MB記憶體。 另外一臺是Vista build 5321,處理器是2GHz 移動PIV,1G記憶體,每次測試我都是取100次演算法運算的平均值,結果單位是毫秒,以下是PIII電腦的執行結果:
沒優化 進行了空間優化 進行了速度優化
Unmanaged 92.88 ± 0.09 88.23 ± 0.09 68.48 ± 0.03
Managed C++ 72.89 ± 0.03 72.26 ± 0.04 71.35 ± 0.06
C++/CLI 73.00 ± 0.05 72.32 ± 0.03 71.44 ± 0.04
C# Managed 72.21 ± 0.04 69.97 ± 0.08
PIV電腦的結果:
沒優化 進行了空間優化 進行了速度優化
Unmanaged 45.2 ± 0.1 30.04 ± 0.04 23.06 ± 0.04
Managed C++ 23.5 ± 0.1 23.17 ± 0.08 23.36 ± 0.07
C++/CLI 23.5 ± 0.1 23.11 ± 0.07 23.80 ± 0.05
C# Managed 23.7 ± 0.1 22.78 ± 0.03
可以看出,非託管程式碼在不同的優化方案上存在很大的效率差異,PIII上不優化比優化慢35%,在PIV上也是。 在這個簡陋的統計上表明,不管是哪種優化方案,管理程式碼在執行效率上並沒有太大區別,編譯器和聯結器並沒有影響到執行效率太多, 我在後面會說更多關於這方面的資訊。
奇怪的是,在Vista下,管理程式碼進行空間優化甚至比進行速度優化速度更快!
C#的結果跟託管的C++比起來,並沒有太大區別,但是可以看到, 優化過的c#程式碼比優化過的託管C++程式碼要稍快些
現在來比較以下託管程式碼和非託管程式碼的結果。 在不優化的情況下,託管程式碼遠遠快於非託管程式碼,這個差距在優化空間後被稍微縮短了點,只有在進行速度優化後,非託管程式碼才比託管程式碼稍稍快上一點
非託管程式碼和C#程式碼的差別只有3%左右,不過,c#程式碼仍然比c++的更快!
.NET的編譯器(在這個情況下是託管的C++程式碼) 可以看成是與非託管C++編譯器的Parser引擎是等價的。編譯器將生成類,方法等的表,然後進行了一系列的高等級優化。 .NET真正的非託管編譯器其實是JIT(即時編譯器):這才是程式真正轉換成低等級的x86程式碼的地方..NET編譯器和JIT編譯的組合,其實跟非託管C++編譯器等價的,唯一的不同是,.Net被分成了兩個部分.事實上,JIT在執行託管程式碼時,對.NET程式針對客戶電腦進行了優化,而不是像非託管程式碼那樣是在程式設計師電腦上進行的優化。結果表明,託管C++程式碼和c#程式碼的優化設定帶來的影響非常小。 顯而易見的是,C#程式碼至少是跟C++程式碼同樣高效。
記住! 在.NET中沒有任何一個部分是自動就必C++程式碼慢的,執行效率完全取決於程式設計師。任何一個告訴你託管程式碼比非託管程式碼慢的人,都是沒有考慮到.NET執行機制的人,簡單的說,就是對.NET一竅不通!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-526495/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 託管與非託管的混合程式設計程式設計
- [.net 物件導向程式設計進階] (8) 託管與非託管物件程式設計
- 重學c#系列——c# 託管和非託管資源與程式碼相關(四)C#
- 託管程式碼和非託管程式碼
- git提交程式碼託管平臺流程Git
- Git程式碼託管常用命令Git
- C# 託管資源和非託管資源C#
- Docker 之 GitLab 區域網程式碼託管DockerGitlab
- .NET Framework非託管相關概念詳解Framework
- 重學c#系列——c# 託管和非託管資源(三)C#
- 博森量化軟體:託管錢包與非託管錢包的區別?
- 從C++看C#託管記憶體與非託管記憶體C++C#記憶體
- 程式碼託管-公司用gitlab,我們用github(一)GitlabGithub
- 你需要託管資料庫嗎?資料庫
- Code:美團程式碼託管平臺的演進與實踐
- 基於Coding程式碼託管的Git基本使用指導Git
- 使用git將自己的程式碼同時儲存在多個程式碼託管平臺Git
- 程式設計師必須知道的幾個Git程式碼託管平臺程式設計師Git
- 託管 AJAX 能否讓 Web 應用程式提速?Web
- 伺服器託管伺服器
- Oracle 託管檔案Oracle
- 華為開發者 雲託管
- 【YashanDB知識庫】ycm託管資料庫時,資料庫非OM安裝無法託管資料庫
- 管中窺豹----.NET Core到.NET 8 託管堆的變遷
- .Net 7 的AOT的程式比託管程式碼更容易破解?
- 伺服器託管是什麼意思,為什麼要託管?伺服器
- Git使用教程3:MyEclipse+Egit+GitHub實現程式碼託管 【上】EclipseGithub
- Git使用教程3:MyEclipse+Egit+GitHub實現程式碼託管 【下】EclipseGithub
- 重學c#系列——非託管例項(五)C#
- 怎樣在Github上託管開原始碼庫Github原始碼
- 翻譯 - ASP.NET Core 託管和部署 - 在 Linux 上使用 Nginx 託管 ASP.NET Core 網站ASP.NETLinuxNginx網站
- 使用GitHub託管專案Github
- 基於Gitea打造一個屬於你自己的程式碼託管平臺Git
- 程式碼託管網站GitHub融資2.5億美元 估值約20億美元網站Github
- 谷歌程式碼託管 GoogleCode中 關於 版本的一個寫法谷歌Go
- Git學習——遷移單一倉庫至其他程式碼託管平臺Git
- ASP.NET Core 託管和部署(一)【Kestrel】ASP.NET
- windows 服務中託管asp.net coreWindowsASP.NET