標籤:

.NET 的性能很差嗎?


MD!寫個循環查上N遍資料庫的,就是彙編性能也不行。而這種代碼,無論是C#還是Java,我都見過太多了。真不是.NET性能差,而是寫代碼的人性能差!


我從大學的時候開始寫第一個C#程序,眼看著.net越來越牛逼了。差不多10年前的時候,我寫的C#程序比起我寫的C++程序慢很多。後來差不多工作了,我發現我寫的C#程序跟我寫的C++程序已經一樣快了。到了今天我發現我寫的C++程序已經趕不上我寫的C#程序的速度了,覺得好痛苦(逃


99.99%的應用程序慢都是因為寫的代碼垃圾而不是語言本身問題,說dotNet慢那為什麼國內的攜程和國外的StackOverflow能寫出性能很好的應用程序?國內互聯網公司以JAVA為主並不是JAVA有多好,而是各大互聯網公司能說話的高級架構師當年都是做JAVA出身的,國內的技術環境註定了人家現在能靠已有技術賺大錢吹大牛逼幹嘛要費大功夫研究另一個技術棧。。。


從運行時來說 CLR 自己現在的 Core CLR 在性能方面的設計已經不錯了。能出現感覺得到的性能問題大部分是由於自己寫的代碼太爛。之前關於 .NET 性能不好的吐槽出現的頻率相比現在多多了,現在隨著准入門檻的提高以及靠譜的社區的發展這種狀況會逐步改善。

所以如果遇到性能問題,首先可以懷疑一下自己的代碼,最後才是基礎設施。


語言本身不是問題,性能差大多在資料庫層。

考慮下操作系統。

特別是伺服器。


今天訓練正好有個字元串的水題,拿c#搞定的,中途超時一次【以為水題暴力就行,暴力過頭了】,然後用List優化了一下,A

下邊是沒優化的,上邊那個耗時233ms送給伺服器的MONO

這個題限時2s,也就是說略微優化了下耗時縮減到1/10以下~

所以程序好不好,還是看個人


據我所知,JVM for Windows性能非常差。

JVM for linux性能不錯,不過比NET CORE還是稍微慢了點。

以上結論只是針對我的測試。也許其他人寫的測試會得出相反的結論也未可知。

我的測試很簡單:

創建一個List,添加10,000,000個整數。

.net core:

List& l = new List&();

for(int i = 0; i &< 10000000; i++) l.Add(i);

JAVA:

ArrayList& al = new ArrayList&();

for(int i = 0; i &< 10000000; i++) al.Add(i);

第一個測試耗時0.1秒,java耗時1.27秒。慢十倍。

因為java有裝箱,有朋友說這不公平。問題是java也沒給人機會創建一個不用裝箱的List類型。

好,下面修改測試,c#使用List&替換List&. java代碼不變。

java耗時1.27秒, net core耗時1.1秒。

再次修改測試,使用LinkedList,java也使用LinkedList。

java耗時2.7秒,net core耗時1.3秒。java慢了一倍。

再次修改測試,使用List&, java使用ArrayList&,分別添加一千萬個「hello」字元串。

java耗時304毫秒,net core耗時190毫秒。

請注意程序運行過程中,VM對內存和CPU的消耗,JVM明顯高於CLR。也就是說,JVM使用了更多的CPU和Memory,但是性能卻低於NET Core。

至於.NET Framework,它只能運行在Windows之上,但是其性能與NET Core for Windows是基本相當的。

不過話說回來,誰會在乎這點性能呢?PHP,python性能比java還差一大截呢,不一樣火的要命。

做系統,主要看生態和效率,至於性能,別太差就行。


極致優化出的C++代碼,並配合合適的編譯器,在與優化方案(比如特定的CPU品牌、核心數)匹配的硬體上執行效率秒殺dotnet。

但是,dotnet的一般代碼,吊打一般C++程序員寫出的未特殊優化的代碼;而且優化dotnet代碼所需的功力、時間都比C++要求低,對優化的特異化(特定硬體適配)要求也低。

問題在於,你是否需要不計成本的開發一個極致高速的程序?


不差。

最快的肯定是彙編和C語言這種直接處理內存的語言,當然寫的不好也更容易崩潰。

其次就是Java和C#這種先編譯,然後虛擬機來解釋執行的語言。由於有即時編譯器的存在,程序在運行一段時間之後會被編譯成本地代碼,速度甚至可以和C++相當。

最差的應該就是PHP、Python這些解釋型語言了,代碼直接由解釋器執行,速度和編譯型語言差了十幾倍到上千倍。當然由於開發效率高,加上現在硬體不值錢了,這些語言用的還是很多的。

結論,.NET可能不是最快的,但絕對比大多數快。

評論有人讓我放測試數據。我只想說,我上面這些話都是想起來以前書上說編譯和解釋的區別之後隨口一說。而且影響語言運行速度的因素有很多,可能在一種情況下A語言快,另一種情況下反而B語言更快。所以單純的測試意義並不大。

不過我還是隨便測了一下,大家看看就好。

先看看Python的,Windows 10 64位系統,版本是Python 3.6.1 在我的渣渣電腦測了4次,用時分別是8.1s 8.3s 8.9s 9.1s。

import time

start = time.time()

for i in range(1, 1000):
sum = 0
for n in range(1, 60001):
sum += n

end = time.time()

print(end - start)

然後是c#,運行環境是 .NET Core,用時基本上都是00:00:00.1920193這個數量級的。

class Program
{
static void Main(string[] args)
{
var start = DateTime.Now;

for (var i = 0; i &< 1000; ++i) { var sum = 0; for (var n = 1; n &<= 60000; ++n) { sum += n; } } var end = DateTime.Now; System.Console.WriteLine(end - start); } }

當然這裡我的測試結果是這個例子下C#更快一點,在不同條件下例如評論中貼的速度對比圖可能Python要更快一點。


相同水平的人寫出的的C#和C++程序,基本沒有明顯區別了。在頻繁分配釋放對象的場景,C#還有明顯優勢。即使C#較慢的場景,大部分也可以用unsafe搞掂,這時候基本就是C的效率了。加上C#語法糖多,開發效率高。算上編碼和調試以及市場的時間成本,大部分場景下,C#優勢明顯。

C#和其它所有的自動回收內存的語言一樣,在使用大內存的時候,STW和GC佔用CPU比較頭疼。

現在碰上問題基本上能用SQL就用SQL,其次是腳本、再不行依次考慮Python、Java/C#。逼到最後才會考慮用C/C++。

C#的問題在於對程序員保護得過度了,對底層了解太少,往往會寫出很恐怖的代碼來。有不少幹了多年C#程序員不知道位元組序、不知道對齊、不知道字符集編碼、不知道IO開銷、不知道對象開銷,不知道正確使用線程,不知道正確的socket操作方式,甚至連位元組和位點對應關係都不知道。


我覺得只有大神級別的語言設計師或者架構師才有資格評價 .NET 的性能。

我等庶民需要關心和提高的是自己寫代碼的水平,因為 99.9999% 的性能問題都與此有關。


大部分程序員還輪不到談論性能這一步,能寫穩定好維護的代碼就不錯了,c#,c++,Java這三種語言,各自用的熟的程序員,寫出來的性能都是差不多的,無非就是c++後期摳性能的空間要大一些


幾個方面說一下.NET的性能:

1、UTF16的string以及其它一些標準庫內容:詳見dotnet/corefxlab ,總之標準庫很多地方選擇了最安全、方便擴展但性能不是最好的方法

2、內存分配:託管堆這個東西吧

比棧慢:這個是沒辦法的事情,.NET對於介面類型是沒辦法僅在棧上操作的,這個也是GC壓力的大頭

比自定義池稍慢:畢竟自定義池可分配的類型有限(往往還唯一), 而託管堆需要應對任何類型

比非託管堆快:無碎片,無需多說

3、各種越界檢查、null檢查,可以說是真正能讓.NET和native體現差距的地方,不過這時為了性能就只能捨棄類型安全性了


https://benchmarksgame.alioth.debian.org/u64q/csharp.html

好吧,雖然這個應該比較權威(客觀),但感覺這樣的測試可能還是有點biased。僅供參考。

個人認為C#還是很有前途的。片面追求的性能只是語言的一個很小的方面。


怎麼可能呢?因為OO編程的緣故,現在的程序大量的數據類型都是引用類型,值類型數據少之又少。所以,託管代碼的優勢是明顯的(GC),比非託管代碼系能高是正常的,但是 C# 處理大量值類型數據和C/C++相比較的話,卻又不如。所以是否用託管代碼,看行業性質吧。


性能差有很多方面的原因,通常在你覺得差的時候,是時候去debug一波了:)

而你的問題沒有一個參考標的,而按照我的標準來說,.NET性能非常好。

如果一定要爭分奪秒,連100ms都不肯放過的話,沒有GUI的純後台會更快;

而.NET就是因為性能不差,寫代碼太過簡單,於是在程序並不大時根本感覺不出來哪裡慢;

而程序越做越大時,總會因為一些遺留的問題導致不知名的卡頓,經過調試才能發現其中有多個多餘的循環,優化優化跑起來又是非常快。

當然這跟你的實力正相關,而實力又跟實踐和優化的研究精神正相關。


看做什麼開發吧,windows應用開發,企業內部小網站開發,還不錯的。然後互聯網,框架比java少,Windows授權費不便宜,大並發群集解決方案沒java成熟


稍稍了解.NET的產生背景,就不至於問這樣的問題,看該問題標記了Java、C#,其實C#的前期馬甲Visual J++已經吊打Java勒,之後因為和Sun公司的官司,微軟重新造了C#,可以說,這是海神在知乎上被黑的最慘的一次。。。


首先優化的C++要比C#快,尤其是矩陣計算之類的數學計算功能,比如用intel處理器,C++用mkl庫的速度比單純的C#寫的矩陣計算速度要快,如果是做其他類型的應用,C#效率還是不錯的,差1毫秒其實真的也感覺不到。雖然說這話不太負責,不過講真,多優化代碼對速度的提升比換語言的提升大得多,單線程變多線程對速度的提升也比換語言的提升大得多,最終boss,換塊cpu的對速度的提升遠大於換語言,如果並行計算,那換塊顯卡對速度的提升簡直是鳥槍換炮。與其考慮到底用哪種代碼寫,我覺得最熟悉的就是最合適的,我個人代碼能力一般,最熟悉的三種代碼恰好是樓上說的c++,c#和python,公司裡面做個數據模型用python,訓練好的模型應用,圖像引擎開發還是c++,最後形成界面用qt或者c#。算是大雜燴吧。:-)


這得看寫程序的人有多牛逼


推薦閱讀:

c#同一button的點擊事件中能寫兩個方法嗎?
現在還有必要學習 GDI 嗎?WPF 能完全替代 GDI 嗎?
如何理解WPF中的依賴項屬性(DependencyProperty)?
學習C#的正確姿勢以及一些問題?

TAG:Java | NET | C# |