絕大多數情況下,都是C++比JAVA快。前者直接編譯成本地機器語言,后者需要虛擬機即時編譯。前者沒有垃圾回收,后者有垃圾回收。前者可以棧上分配資源,后者依賴編譯器和虛擬機(不確定性)。
但是也需要清楚,在某些時候,JAVA速度更快。這是建立在C++還沒有精通或者不想花時間優化的前提下。JAVA的虛擬機有時非常智能,它可以自動對代碼進行優化。而C++編譯器則優化空間較少,它的哲學是把更多的優化機會留給程序員。
JAVA虛擬機常見的自動優化有以下這些。自動把某些資源放到棧上分配,自動把某些函數設置為內聯。還有更厲害的,內存池。采用內存池時(預先分配一大塊),內存分配會有一定提速,也防止了內存碎片。還有緩存技術,把一些可能經常用的對象預先分配,以后每次new的時候直接用現成的。也就是表面上看是new了個對象,實際上并沒有發生分配內存的動作,而是直接使用全局的一個可以反復重用的對象指針。還有“寫時修改”策略。即克隆一個大對象時,并沒有真正克隆(僅僅是復制一個指針),而是直到發現新對象變更時才真正克隆。
這些優化,用C++通通都可以做,而且還可以手動做,不依賴編譯器自動優化(JAVA通常依賴自動優化,不能手動)。C++要做的就是該棧上分配的就棧上分配,該內聯的就內聯(內聯不了的直接少調用函數,或寫成宏)。順便說一下,JAVA似乎都沒有棧上分配(除了基本類型)和內聯的概念,因為是靠虛擬機自動智能實現的。更加復雜的就是內存池了,自己實現一個內存池。另外還有多用緩存,不要什么東西都從堆上新分配。
但是現實情況是,多數C++程序員都沒有這些優化能力,或者即使有也沒有那個時間折騰,趕工期嘛。還有一點很重要,性能優化后的代碼往往可讀性都很差,而且代碼變復雜!這就導致了,在某些時候,類似的代碼,JAVA速度反而更快。
最后,還需要強調,上面說的JAVA有時候比C++快,這種情況并不多見。有也是經常發生在C++初學者身上。而且只要是C++代碼經過高度的優化,基本上是一定比高度優化的JAVA要快的!
我們可以把C++比喻成有強大功能(光圈,變焦,曝光時間等)的相機,而JAVA是高度智能的一鍵式傻瓜式相機。當一個不會手動調參的攝影師用專業相機時,并不一定比一鍵式傻瓜相機自動調參拍出來的效果好。而一個專業攝影師,則一定拍出來比傻瓜式相機效果好。