相同的時間複雜度下,為什麼 C# 運行速度 比 C++ 快?
(1)感謝諸位的解答,今天我在VS下,選擇「開始執行(不調試)」,並且選擇「release」,最後在10秒內跑完。。。(雖然不知道選擇這種執行方式對不對)
----------------------------------------------------------------------------------(2)最近做到一道題目,發現調用std::string::operator+()和string.substr()很多次後,直接導致TLE,但是相同思路換種實現方式,就可以了。。這個也應該是我所提的問題C++比C#慢一些的原因之一。今天忽然想起以前提的這個問題,當時不是很理解一些回答,現在恍然大悟,謝謝。。。。 ------ 2015.12.02----------------------------------------------------------------------------------
課設是要求做有關中文文字處理的,我用的C++寫的,而另一個同學用的C#寫的,核心演算法一樣,時間複雜度也相同,但是我的C++代碼需要跑幾分鐘,而另外一個同學幾秒鐘就跑完了。請問一下,這是為什麼啊?(我一直以為,C++主要用於寫底層的代碼,相同的時間複雜度下,應該很快,為什麼現在不如C#了呢?求解。。。)代碼請見:Ubuntu Pastebin
不要用debug版和人家release版比性能。
我見過很多新手是不知道還有release版的,另外分不清run和debug run的也大有人在。
VC++的debug run下,程序結束時是要檢測內存泄漏和溢出的,這個過程非常慢,如果你有大量分配內存,那麼這個過程有幾分鐘都不奇怪。C#就沒這個問題。這麼離譜的差距我想是語言本身問題的可能性不大。
估計用了不當的方法寫C++。例如做了大量std::string::operator+()。但可能性太多,無代碼無法判斷。
有什麼好猜的,Profiling啊,多簡單的事情。
答題者看到你的描述一般是不會相信的,除非你把代碼貼出來詳細討論一下。
大哥你是不是把編譯時間算在裡面了?
我正想藉此表達下我的一個觀點(雖然v大也回答了這個問題)。
語言本質在於翻譯(的程度),所以理論上速度是C#&<=C++。
但有一個條件就是翻譯的質量(也就是是實現者的能力)。
那麼完全可能C#&>=C++。
一聽「文字處理」就知道為什麼了,話說std::string不是像你那樣用的。
三個字,上代碼
看下空間的複雜度,在是受限的內存下GC一次要人命。
如果說C#比C++性能高的地方的話,其實不多,很容易就能猜出來。譬如說你的演算法依賴於大量的new小對象,這種時候C#肯定要比C++快很多倍。
題主確定你倆的演算法是一樣的?
talk is cheap show me the code
題主,送你一句話:「以你代碼實現的質量之低,還輪不到拼演算法的時間複雜度的地步」。
- - - - -
首先向題主 @Jming S 道歉,自己圖一時口快沒有好好回答問題。
雖然自己沒有多少時間,但是我會把這個問題回答完。留原答案以作警示。看了一下代碼,有很多地方可能會出現性能損失,但是由於用的電腦不是自己的,上面也沒法安裝編譯器,我也沒有測試用的數據,所以還請題主對每個函數分別測時,再對症下藥。
- - - - -以下是我對每個函數的分析,側重於 STL 的使用。InitText
如果我們用類似流程圖的東西來表示數據的拷貝/處理過程的話,應該是這樣:ifstream → ostringstream → string →(for 循環)→ string你的目的是遍歷整個文件,並進行 decoding,但是為什麼要做兩次多餘的拷貝呢?我看到你的注釋里已經提到了流,說明你已經懂得這個概念了,為什麼不好好利用呢?所有基於 basic_istream 的類都有兩個非常好用的函數:std::basic_istream::peek 和 std::basic_istream::get (點擊以查看用法)。有了這兩個函數,你可以一個循環就搞定。
getOneWord, getTwoWord, getThreeWord這三個函數大致相同,就放在一塊分析。string →(for 循環中 substr)→ unordered_map → vector → 文件- 開銷比較大的操作就在 substr 函數上,因為對於每個詞,都會創建一個 string 對象。因為你要存儲的詞都不超過 3 個字元,所以不妨用一個結構體來存儲詞。這樣就避免了 substr 的開銷。
- 另外一個需要考慮的地方是,如果你需要排序,並且數據量並不算很大,可以嘗試用 map 代替 unordered_map,因為 map 是排序的,所以可以直接遍歷迭代器輸出。
- 三個函數可以合併成一個函數,共用一個 vector 以避免重複申請內存的開銷。
所謂c#跑的比c++快,拋去代碼本身的原因,在某些情況下:
c#發布的是中間代碼,CLI虛擬機會在第一次執行時編譯成最適用當前cpu型號的彙編指令。而c++是直接按程序員的設置,編譯成彙編指令,二進位方式發布。這就好比,c++是大工廠通用製品,c#會按照用戶情況自動定製。
然而,至於定製後是否真的能快,快了多少,很多時候是難說的。------------------------------------------------------------------------------------不過問主的困惑,不用懷疑,肯定是代碼寫的太爛。。。理論上C++是可以做到比C#快的,畢竟少一層,但是只能快一點點。可是為了把程序寫成性能相當,付出的努力C#要低很多很多。上代碼吧,讓大家參考參考。
別用奔4和人家i7比。
其實我想弱弱說一句,這還得看電腦配置……
少年……演算法差不多,時間差這麼多,不是你自己代碼寫錯了的話,你考慮下是不是拷貝構造函數調用太多了………
粗看了一下題主的代碼,建議注意臨時對象…
推薦閱讀:
※在C++編程實踐中,我們是否應該放棄使用realloc這個函數?
※初二學生能不能學C++?
※visual studio為什麼把很多posix函數標記為deprecated?
※長期用 C++ 和 MATLAB 做機器學習的你,有沒有遇到一個讓你相見恨晚的語言或包?