? “C++比Java快”,“Java運(yùn)行于虛擬機(jī)上,當(dāng)然要比C++慢”,“C++生成的是本地代碼,直接運(yùn)行于本地硬件上”,“速度比Java快多了”......
??? 這是我一年前學(xué)Java時(shí)的想法,為什么有那些想法?很簡單,人云亦云罷了。既然那么多“高手”都這么說,那么多“精通”Java和C++的人都那么說,自然而然就信了。
??? 就這么過去了一年,對Java也越來越熟悉。自己依然是個(gè)初學(xué)者,而且相信不上升到布盧斯.艾克爾那個(gè)高度,就別想說自己精通C++和Java!
??? 雖說仍舊是初學(xué)者,卻對國內(nèi)那些“高手高手高高手”們的一些言論有了懷疑:Java不比C++慢!然而無論我在哪個(gè)論壇上,那個(gè)技術(shù)群里頭發(fā)表這個(gè)觀點(diǎn),立刻會(huì)有一群“高手”來糾正,甚至有一次一個(gè)號稱“一般不學(xué)語言,要學(xué)兩個(gè)禮拜就能搞定”的“高手”很鄭重其事地向我說明原理。當(dāng)我了解到此人Java才學(xué)了一個(gè)月的時(shí)候,實(shí)在是無語了。還要一次一個(gè)高手批駁我,于是乎小心問了句,了解C語言里malloc和free函數(shù)的機(jī)制與否。此“高手”很不屑地告訴我:C++里的new 和 delete就能搞定,malloc早就沒用了。又無語:也許他用的“C++"是他自己發(fā)明吧。
?? 只想問一句那些“高手”,看過近年來Java PK C++的一些精彩報(bào)告沒?那些報(bào)告可是國外權(quán)威機(jī)構(gòu)的文獻(xiàn)?。∈峭ㄟ^實(shí)驗(yàn)得來的數(shù)據(jù)!
?? 還想問一句:你們說Java慢,是什么人,什么時(shí)候說的?那些言論的源頭,大多數(shù)是Java 1.2時(shí)代以前的啊。
? 說Java比C++慢的人,是否真的親自寫過測試代碼?(雖說我的代碼不能算精確,但也好歹做過近十次的實(shí)驗(yàn),用了好幾種不同的JVM或Cpp編譯器,Java大獲全勝)
? 說Java比C++慢的人,是否了解JVM的運(yùn)行機(jī)制?(我只能說我了解一些罷了)
? 說Java比C++慢的人,是否有拿得出手的報(bào)告或?qū)嶒?yàn)?(可惜,從來沒遇到過)
? 說Java比C++慢的人,請去學(xué)習(xí)一下唯物論!
??而且為什么只有在國外才有那么多人認(rèn)為Java快,只有國外的科研機(jī)構(gòu)才花費(fèi)時(shí)間和精力去做那些被很多國內(nèi)程序員斥為“沒用”(和好多程序員聊天時(shí),他們這么認(rèn)為)的實(shí)驗(yàn)?是中國的程序員都是天才么?還是中國的計(jì)算機(jī)業(yè)太“先進(jìn)”了,不需要去關(guān)心這些東西呢?
? 實(shí)在是發(fā)人深?。。?!
???
FeedBack:
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
2006-06-29 11:15 | fjchenq
為什么說java比c++慢。
有一個(gè)很簡單的事實(shí)說明,為什么java沒有用在開發(fā)操作系統(tǒng)、驅(qū)動(dòng)程序等等底層的程序上。
如果說java不比c++慢,那只有一個(gè)條件下,那就是內(nèi)存足夠大,java的實(shí)現(xiàn)把許多東西都放入內(nèi)存中。這就是為什么delphi在256M內(nèi)存可以跑的很流暢,而jbuilder在512M內(nèi)存下,還跑得相當(dāng)慢。
如果你有足夠大的內(nèi)存,開發(fā)java程序也很快呀。
oracle 8i和oracle8兩個(gè)軟件其實(shí)相當(dāng)不大,但是oracle8i對內(nèi)存要求高得很多,為什么呢?因?yàn)閛racle8i有一部分用java開發(fā)的。
如果你不相信這點(diǎn),oracle10g安裝到256M內(nèi)存的電腦試試,我相信你會(huì)吐血。我曾經(jīng)試過,花的一個(gè)下午還沒有安裝結(jié)束。
總得來說,如果你開發(fā)web程序等,推薦用jsp和.net技術(shù)。這兩種技術(shù)相對來說比較簡單。
回復(fù) 更多評論
有一個(gè)很簡單的事實(shí)說明,為什么java沒有用在開發(fā)操作系統(tǒng)、驅(qū)動(dòng)程序等等底層的程序上。
如果說java不比c++慢,那只有一個(gè)條件下,那就是內(nèi)存足夠大,java的實(shí)現(xiàn)把許多東西都放入內(nèi)存中。這就是為什么delphi在256M內(nèi)存可以跑的很流暢,而jbuilder在512M內(nèi)存下,還跑得相當(dāng)慢。
如果你有足夠大的內(nèi)存,開發(fā)java程序也很快呀。
oracle 8i和oracle8兩個(gè)軟件其實(shí)相當(dāng)不大,但是oracle8i對內(nèi)存要求高得很多,為什么呢?因?yàn)閛racle8i有一部分用java開發(fā)的。
如果你不相信這點(diǎn),oracle10g安裝到256M內(nèi)存的電腦試試,我相信你會(huì)吐血。我曾經(jīng)試過,花的一個(gè)下午還沒有安裝結(jié)束。
總得來說,如果你開發(fā)web程序等,推薦用jsp和.net技術(shù)。這兩種技術(shù)相對來說比較簡單。
回復(fù) 更多評論
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
2006-06-29 14:30 | murainwood
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
2006-06-29 14:39 | murainwood
Java的就是以內(nèi)存換速度的
現(xiàn)在的內(nèi)存好像已經(jīng)蠻便宜了吧?再者,我想現(xiàn)在你也不會(huì)用256M內(nèi)存的機(jī)器來使用oracle10。
C語言是必不可少的(操作系統(tǒng),游戲引擎),但是C++的地位卻有些“尷尬”,不是么?STL庫讓曾經(jīng)C++達(dá)到巔峰,然而巔峰之后?曾經(jīng)有段時(shí)間我非常喜歡STL,然而STL的語法風(fēng)格實(shí)在是欠缺優(yōu)美
C++/CLI被標(biāo)準(zhǔn)委員會(huì)否決,實(shí)在太讓人失望了。 回復(fù) 更多評論
現(xiàn)在的內(nèi)存好像已經(jīng)蠻便宜了吧?再者,我想現(xiàn)在你也不會(huì)用256M內(nèi)存的機(jī)器來使用oracle10。
C語言是必不可少的(操作系統(tǒng),游戲引擎),但是C++的地位卻有些“尷尬”,不是么?STL庫讓曾經(jīng)C++達(dá)到巔峰,然而巔峰之后?曾經(jīng)有段時(shí)間我非常喜歡STL,然而STL的語法風(fēng)格實(shí)在是欠缺優(yōu)美
C++/CLI被標(biāo)準(zhǔn)委員會(huì)否決,實(shí)在太讓人失望了。 回復(fù) 更多評論
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
2006-06-29 14:47 | murainwood
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???[未登錄]
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
2008-03-13 12:04 | Jonlee
Why Java Will Always Be Slower than C++
by Dejan Jelovic
為什么Java永遠(yuǎn)比C++慢?
耍過Java程序,或者用Java碼過程序的人都曉得,Java要比用C++寫成的原生程序要慢。這是咱用Java時(shí)已經(jīng)承認(rèn)的事實(shí)。
不過,很多人想要說服我們說這只不過是暫時(shí)的,他們說Java從設(shè)計(jì)上來講并不慢,相反,只是現(xiàn)在的JIT實(shí)現(xiàn)相對比較嫩,有很多能優(yōu)化的地方JIT并沒有優(yōu)化到,拖了后腿。其實(shí)不然,不管JIT們多牛,Java永遠(yuǎn)要比C++慢。
我想說...
宣揚(yáng)Java不慢于C++的人往往是覺得,(語法)嚴(yán)格的語言,可以讓編譯有更大的優(yōu)化空間。因此,除非你想做人肉編譯器優(yōu)化整個(gè)程序,否則通常都是編譯器做得更好。
這是真的。在數(shù)值計(jì)算領(lǐng)域,F(xiàn)ortran仍然勝于C++,的確因?yàn)樗鼑?yán)格。不用擔(dān)心指針瞎攪和,編譯器可以更安心地優(yōu)化。C++想打敗Fortran的唯一辦法,就是好好設(shè)計(jì)一個(gè)像Blitz++那樣的庫。
測試...
Java可以跟得上C++的地方,就是基準(zhǔn)測試。計(jì)算起第N個(gè)斐波納契數(shù),或者運(yùn)行起Linpack,Java沒理由不跟C++跑得一樣快。當(dāng)所有的計(jì)算都放在一個(gè)類里,并且只使用基本的數(shù)據(jù)類型,比如說int或者double時(shí),Java編譯器的確能跟得上C++的腳步。
事實(shí)...
當(dāng)開始在程序中使用對象的時(shí)候,Java就放松了潛在的優(yōu)化。這一節(jié)會(huì)告訴你為什么。
1. 所有的對象都是從堆里分配的。
Java從棧里分配的,就只有基本數(shù)據(jù)類型,如int,或者double,還有對象的引用。所有的對象都是從堆里分配的。
當(dāng)有大量語義上是一回事的對象時(shí),這不成問題。C++同樣也是從堆上分配這些對象。但是,當(dāng)有值語義不同的小對象時(shí),這就是一個(gè)主要的性能殺手。
什么是小對象?對我來說,就是迭代器們。在設(shè)計(jì)中,我用了很多迭代器。別人可能會(huì)用復(fù)數(shù)。3D程序員可能會(huì)矢量或者點(diǎn)類。處理時(shí)間序列的人可能會(huì)有時(shí)間類。使用這些類的人,無一例外地討厭把不費(fèi)時(shí)間的棧上分配換成花費(fèi)固定時(shí)間的堆上分配。假如把它放在一個(gè)循環(huán)里,就變成了O(n)對0了。如果再加一層循環(huán),沒錯(cuò),又變成O(n^2)對0了。
2. 大量的轉(zhuǎn)換。
得益于模板,好的C++程序員甚至可以寫于完全沒有轉(zhuǎn)換的牛程序。不幸,Java沒有模板,所以Java代碼總是充滿了轉(zhuǎn)換。
對于性能,它們意味著什么?呃,在Java里所有的轉(zhuǎn)換都是很費(fèi)時(shí)的動(dòng)態(tài)轉(zhuǎn)換。多費(fèi)時(shí)?想想你可能會(huì)怎么樣實(shí)現(xiàn)轉(zhuǎn)換的:
最快的方法就是,給每一個(gè)類賦值一個(gè)序號,然后用一個(gè)矩陣來描述任意兩個(gè)類是否相關(guān)的。如果是的話,需要給指針加上多少的位移才能進(jìn)行轉(zhuǎn)換。這種方法的偽碼看起來應(yīng)該是這樣的:
DestinationClass makeCast (Object o, Class destinationClass) {
Class sourceClass = o.getClass (); // JIT compile-time
int sourceClassId = sourceClass.getId (); // JIT compile-time
int destinationId = destinationClass.getId ();
int offset = ourTable [sourceClassId][destinationClassId];
if (offset != ILLEGAL_OFFSET_VALUE) {
return <object o adjusted for offset>;
}
else {
throw new IllegalCastException ();
}
}
好一堆代碼。這只是一個(gè)簡單的情景——用矩陣來表示類的關(guān)系浪費(fèi)了一部分內(nèi)存,沒有哪個(gè)成熟的編譯器會(huì)這樣子做。他們會(huì)使用map或者遍歷繼承樹,這樣會(huì)變得更慢。
3. 攀升的內(nèi)存占用。
Java程序儲存數(shù)據(jù)占用的內(nèi)存大概是相當(dāng)?shù)腃++程序的兩倍。原因如下:
1. 啟用了垃圾收集的程序一般都比不使用垃圾收集的程序多花50%的內(nèi)存。
2. 本來C++里在棧上分配的對象,到了Java就在堆上分配了。
3. Java對象比較大,因?yàn)樗械膶ο蠖加幸粋€(gè)虛表,還要加上對(線程)同步的原生支持。
大的內(nèi)存映像讓程序更大概率被放到磁盤的交換區(qū)去。沒有什么比交換文件更慢的了。
4. 缺少更細(xì)致的控制。
Java原來就是作為一種簡單的語言來設(shè)計(jì)的。很多在C++里讓程序員控制細(xì)節(jié)的特性在Java里都被一腳踢開了。
比如說,在C++里可以改進(jìn)引用的位置(?)?;蛘咭淮紊暾埡歪尫藕芏鄠€(gè)對象。或者用指針?biāo)R恍┬〖记?,更快地訪問成員。
5. 沒有高層次的優(yōu)化。
程序員處理高層次的概念。而編譯器處理剩下的低層次概念。對于程序員來說,一個(gè)叫Matrix的類就代表了比一個(gè)叫Vector的類更高層次的概念。而對于編譯器來說,這些名字都是符號表的一個(gè)入口。他們只關(guān)心類里面有哪些函數(shù),函數(shù)里面有哪些語句。
這樣想一下,比如說要實(shí)現(xiàn)一個(gè)exp(double x, double y)函數(shù),計(jì)算出x的y次冪。對于一個(gè)編譯器,它能只看一下這個(gè)函數(shù),然后指出,exp(exp(x, 2), 0.5)可以優(yōu)化成x自己嗎?當(dāng)然不行。
編譯器能做的優(yōu)化只是語句層面的,而y是在編譯器里面的。即使程序員知道兩個(gè)函數(shù)是對稱的,可以把它們都消去,或者函數(shù)的調(diào)用順序只是相反的,除非編譯器能只瞄一下語句,然后指出來,不然優(yōu)化是不可能完成的。
所以,如果想要完成一個(gè)高水平的優(yōu)化,必須存在某種方法,可以讓程序員來告訴編譯器優(yōu)化的規(guī)則。
沒有哪個(gè)流行的程序語言/系統(tǒng)可以做到這點(diǎn),至少已知的方法,比如微軟承諾的智能語言,都不能。即便如此,在C++里可以用模板元編程來實(shí)現(xiàn)對高層次對象的優(yōu)化。臨時(shí)消除,部分求值,對稱函數(shù)調(diào)用的消去,和其它可以用模板實(shí)現(xiàn)的優(yōu)化。當(dāng)然,不是所有的高層次優(yōu)化都可以這樣做。并且實(shí)現(xiàn)這些東西相當(dāng)麻煩。但是大多數(shù)都可以完成,有人已經(jīng)用這些技術(shù)實(shí)現(xiàn)了好些時(shí)髦的庫。
不幸的是,Java沒有任何元編程的特質(zhì),因此在Java中不會(huì)有這種高層次的優(yōu)化。
所以...
由于存在這種語言特性,Java不可能達(dá)到C++這種速度。這相當(dāng)程序上暗示了,對于要求高性能的軟件和競爭激烈的COTS舞臺上,使用Java不是一種明智的選擇。但是因?yàn)樗途彽膶W(xué)習(xí)曲線,它的容錯(cuò),和它龐大的標(biāo)準(zhǔn)庫,所以適合開發(fā)中小型自用和定制軟件。
附記...
1. 有人向James Gosling(誰?google之...)提交了很多可以改進(jìn)Java性能的語言特性。文本在這里。不幸的是,Java語言已經(jīng)有四年沒有改動(dòng)過了,所以看起來這些提議似乎不會(huì)在一夜之間被實(shí)現(xiàn)。
2. 最有可能往Java里加入泛型的是Generic Java。又很不幸的是,GJ只是通過在編譯時(shí)把所有類型信息去掉來支持泛型。所以最后面執(zhí)行環(huán)境看到的,仍然是緩慢的轉(zhuǎn)換。
3. 垃圾收集的FAQ包含了關(guān)于垃圾收集慢于定制分配器的信息(上面第四點(diǎn))。
4. 這里是一篇宣稱垃圾收集比棧分配的快的文章。但是它的要求是物理內(nèi)存必須是程序?qū)嶋H需要的內(nèi)存的七倍之多。還有,它描述的是一種stop-and-copy(是不是那種執(zhí)行到一半,然后停下來,把內(nèi)存拷到另外一塊內(nèi)存,同時(shí)清除垃圾的那種方法?),而且還不是并發(fā)的。
反饋...
我收到很多關(guān)于這篇文章的反饋。附上一些典型的評論,還有我的回答:
“你還忘記了指出在Java里所有的方法都是虛方法,因?yàn)闆]有人會(huì)加上final關(guān)鍵字?!?
事實(shí)上,不使用final關(guān)鍵字不是問題的關(guān)鍵所在,使用者才是。同時(shí),虛函數(shù)也沒有問題,但是卻失去了優(yōu)化機(jī)會(huì)。自從JIT們知道怎么樣內(nèi)聯(lián)虛函數(shù),這就變得不那么顯著了。
JIT可以內(nèi)聯(lián)虛函數(shù),所以Java可以比C++更快。
C++也可以使用JIT編譯。不信的可以看看.NET的C++編譯器。
到最后的時(shí)候,速度并不重要。電腦浪費(fèi)了大部份時(shí)間在等待用戶輸入。
速度仍然很重要。我仍然在等我的筆記本啟動(dòng)起來,我在等我的編譯器停下來,我還要等Word打開一個(gè)超長的文檔。
我在一個(gè)金融公司工作。有時(shí)候我必須對一個(gè)很大的數(shù)據(jù)集進(jìn)行模擬。速度在這種情況下都很重要。
有些JIT可以在棧上分配一些對象。
當(dāng)然,一些。
你的轉(zhuǎn)換代碼看起來很丑??梢栽陬惖睦^承層次上檢查類。
首先,這樣只比矩陣查找快一點(diǎn)點(diǎn)而已。
第二,這樣只能查找類,類只占多少?低層次的細(xì)節(jié)往往是通過接口來實(shí)現(xiàn)的。
哈,那么我們都應(yīng)該使用匯編?
不是的,我們都要使用對業(yè)務(wù)有用的語言。Java提供了龐大的標(biāo)準(zhǔn)庫,讓很多任務(wù)變得容易,因此Java是偉大的。它比其它所有的語言更容易移植(但并非100%可移植——不同的平臺有不同問題)。它具有垃圾收集機(jī)制,簡化了內(nèi)存管理,同時(shí)也讓某些構(gòu)造如閉包可實(shí)現(xiàn)。
但是,同時(shí),Java和所有的語言一樣,也有瑕疵。在值語義的類型上缺少支持。它的同步并不是很有效率。它的標(biāo)準(zhǔn)庫建立在異常檢查之上,把實(shí)現(xiàn)拖進(jìn)了接口。它的性能可以更好。它的數(shù)學(xué)庫有些惱人的問題。諸如此類。
這些缺憾都是大問題嗎?看你用它做什么。因此,在幾種語言里,連同它的編譯器以及可以選擇的類庫里選擇對你的工程有利的一種。
回復(fù) 更多評論
by Dejan Jelovic
為什么Java永遠(yuǎn)比C++慢?
耍過Java程序,或者用Java碼過程序的人都曉得,Java要比用C++寫成的原生程序要慢。這是咱用Java時(shí)已經(jīng)承認(rèn)的事實(shí)。
不過,很多人想要說服我們說這只不過是暫時(shí)的,他們說Java從設(shè)計(jì)上來講并不慢,相反,只是現(xiàn)在的JIT實(shí)現(xiàn)相對比較嫩,有很多能優(yōu)化的地方JIT并沒有優(yōu)化到,拖了后腿。其實(shí)不然,不管JIT們多牛,Java永遠(yuǎn)要比C++慢。
我想說...
宣揚(yáng)Java不慢于C++的人往往是覺得,(語法)嚴(yán)格的語言,可以讓編譯有更大的優(yōu)化空間。因此,除非你想做人肉編譯器優(yōu)化整個(gè)程序,否則通常都是編譯器做得更好。
這是真的。在數(shù)值計(jì)算領(lǐng)域,F(xiàn)ortran仍然勝于C++,的確因?yàn)樗鼑?yán)格。不用擔(dān)心指針瞎攪和,編譯器可以更安心地優(yōu)化。C++想打敗Fortran的唯一辦法,就是好好設(shè)計(jì)一個(gè)像Blitz++那樣的庫。
測試...
Java可以跟得上C++的地方,就是基準(zhǔn)測試。計(jì)算起第N個(gè)斐波納契數(shù),或者運(yùn)行起Linpack,Java沒理由不跟C++跑得一樣快。當(dāng)所有的計(jì)算都放在一個(gè)類里,并且只使用基本的數(shù)據(jù)類型,比如說int或者double時(shí),Java編譯器的確能跟得上C++的腳步。
事實(shí)...
當(dāng)開始在程序中使用對象的時(shí)候,Java就放松了潛在的優(yōu)化。這一節(jié)會(huì)告訴你為什么。
1. 所有的對象都是從堆里分配的。
Java從棧里分配的,就只有基本數(shù)據(jù)類型,如int,或者double,還有對象的引用。所有的對象都是從堆里分配的。
當(dāng)有大量語義上是一回事的對象時(shí),這不成問題。C++同樣也是從堆上分配這些對象。但是,當(dāng)有值語義不同的小對象時(shí),這就是一個(gè)主要的性能殺手。
什么是小對象?對我來說,就是迭代器們。在設(shè)計(jì)中,我用了很多迭代器。別人可能會(huì)用復(fù)數(shù)。3D程序員可能會(huì)矢量或者點(diǎn)類。處理時(shí)間序列的人可能會(huì)有時(shí)間類。使用這些類的人,無一例外地討厭把不費(fèi)時(shí)間的棧上分配換成花費(fèi)固定時(shí)間的堆上分配。假如把它放在一個(gè)循環(huán)里,就變成了O(n)對0了。如果再加一層循環(huán),沒錯(cuò),又變成O(n^2)對0了。
2. 大量的轉(zhuǎn)換。
得益于模板,好的C++程序員甚至可以寫于完全沒有轉(zhuǎn)換的牛程序。不幸,Java沒有模板,所以Java代碼總是充滿了轉(zhuǎn)換。
對于性能,它們意味著什么?呃,在Java里所有的轉(zhuǎn)換都是很費(fèi)時(shí)的動(dòng)態(tài)轉(zhuǎn)換。多費(fèi)時(shí)?想想你可能會(huì)怎么樣實(shí)現(xiàn)轉(zhuǎn)換的:
最快的方法就是,給每一個(gè)類賦值一個(gè)序號,然后用一個(gè)矩陣來描述任意兩個(gè)類是否相關(guān)的。如果是的話,需要給指針加上多少的位移才能進(jìn)行轉(zhuǎn)換。這種方法的偽碼看起來應(yīng)該是這樣的:
DestinationClass makeCast (Object o, Class destinationClass) {
Class sourceClass = o.getClass (); // JIT compile-time
int sourceClassId = sourceClass.getId (); // JIT compile-time
int destinationId = destinationClass.getId ();
int offset = ourTable [sourceClassId][destinationClassId];
if (offset != ILLEGAL_OFFSET_VALUE) {
return <object o adjusted for offset>;
}
else {
throw new IllegalCastException ();
}
}
好一堆代碼。這只是一個(gè)簡單的情景——用矩陣來表示類的關(guān)系浪費(fèi)了一部分內(nèi)存,沒有哪個(gè)成熟的編譯器會(huì)這樣子做。他們會(huì)使用map或者遍歷繼承樹,這樣會(huì)變得更慢。
3. 攀升的內(nèi)存占用。
Java程序儲存數(shù)據(jù)占用的內(nèi)存大概是相當(dāng)?shù)腃++程序的兩倍。原因如下:
1. 啟用了垃圾收集的程序一般都比不使用垃圾收集的程序多花50%的內(nèi)存。
2. 本來C++里在棧上分配的對象,到了Java就在堆上分配了。
3. Java對象比較大,因?yàn)樗械膶ο蠖加幸粋€(gè)虛表,還要加上對(線程)同步的原生支持。
大的內(nèi)存映像讓程序更大概率被放到磁盤的交換區(qū)去。沒有什么比交換文件更慢的了。
4. 缺少更細(xì)致的控制。
Java原來就是作為一種簡單的語言來設(shè)計(jì)的。很多在C++里讓程序員控制細(xì)節(jié)的特性在Java里都被一腳踢開了。
比如說,在C++里可以改進(jìn)引用的位置(?)?;蛘咭淮紊暾埡歪尫藕芏鄠€(gè)對象。或者用指針?biāo)R恍┬〖记?,更快地訪問成員。
5. 沒有高層次的優(yōu)化。
程序員處理高層次的概念。而編譯器處理剩下的低層次概念。對于程序員來說,一個(gè)叫Matrix的類就代表了比一個(gè)叫Vector的類更高層次的概念。而對于編譯器來說,這些名字都是符號表的一個(gè)入口。他們只關(guān)心類里面有哪些函數(shù),函數(shù)里面有哪些語句。
這樣想一下,比如說要實(shí)現(xiàn)一個(gè)exp(double x, double y)函數(shù),計(jì)算出x的y次冪。對于一個(gè)編譯器,它能只看一下這個(gè)函數(shù),然后指出,exp(exp(x, 2), 0.5)可以優(yōu)化成x自己嗎?當(dāng)然不行。
編譯器能做的優(yōu)化只是語句層面的,而y是在編譯器里面的。即使程序員知道兩個(gè)函數(shù)是對稱的,可以把它們都消去,或者函數(shù)的調(diào)用順序只是相反的,除非編譯器能只瞄一下語句,然后指出來,不然優(yōu)化是不可能完成的。
所以,如果想要完成一個(gè)高水平的優(yōu)化,必須存在某種方法,可以讓程序員來告訴編譯器優(yōu)化的規(guī)則。
沒有哪個(gè)流行的程序語言/系統(tǒng)可以做到這點(diǎn),至少已知的方法,比如微軟承諾的智能語言,都不能。即便如此,在C++里可以用模板元編程來實(shí)現(xiàn)對高層次對象的優(yōu)化。臨時(shí)消除,部分求值,對稱函數(shù)調(diào)用的消去,和其它可以用模板實(shí)現(xiàn)的優(yōu)化。當(dāng)然,不是所有的高層次優(yōu)化都可以這樣做。并且實(shí)現(xiàn)這些東西相當(dāng)麻煩。但是大多數(shù)都可以完成,有人已經(jīng)用這些技術(shù)實(shí)現(xiàn)了好些時(shí)髦的庫。
不幸的是,Java沒有任何元編程的特質(zhì),因此在Java中不會(huì)有這種高層次的優(yōu)化。
所以...
由于存在這種語言特性,Java不可能達(dá)到C++這種速度。這相當(dāng)程序上暗示了,對于要求高性能的軟件和競爭激烈的COTS舞臺上,使用Java不是一種明智的選擇。但是因?yàn)樗途彽膶W(xué)習(xí)曲線,它的容錯(cuò),和它龐大的標(biāo)準(zhǔn)庫,所以適合開發(fā)中小型自用和定制軟件。
附記...
1. 有人向James Gosling(誰?google之...)提交了很多可以改進(jìn)Java性能的語言特性。文本在這里。不幸的是,Java語言已經(jīng)有四年沒有改動(dòng)過了,所以看起來這些提議似乎不會(huì)在一夜之間被實(shí)現(xiàn)。
2. 最有可能往Java里加入泛型的是Generic Java。又很不幸的是,GJ只是通過在編譯時(shí)把所有類型信息去掉來支持泛型。所以最后面執(zhí)行環(huán)境看到的,仍然是緩慢的轉(zhuǎn)換。
3. 垃圾收集的FAQ包含了關(guān)于垃圾收集慢于定制分配器的信息(上面第四點(diǎn))。
4. 這里是一篇宣稱垃圾收集比棧分配的快的文章。但是它的要求是物理內(nèi)存必須是程序?qū)嶋H需要的內(nèi)存的七倍之多。還有,它描述的是一種stop-and-copy(是不是那種執(zhí)行到一半,然后停下來,把內(nèi)存拷到另外一塊內(nèi)存,同時(shí)清除垃圾的那種方法?),而且還不是并發(fā)的。
反饋...
我收到很多關(guān)于這篇文章的反饋。附上一些典型的評論,還有我的回答:
“你還忘記了指出在Java里所有的方法都是虛方法,因?yàn)闆]有人會(huì)加上final關(guān)鍵字?!?
事實(shí)上,不使用final關(guān)鍵字不是問題的關(guān)鍵所在,使用者才是。同時(shí),虛函數(shù)也沒有問題,但是卻失去了優(yōu)化機(jī)會(huì)。自從JIT們知道怎么樣內(nèi)聯(lián)虛函數(shù),這就變得不那么顯著了。
JIT可以內(nèi)聯(lián)虛函數(shù),所以Java可以比C++更快。
C++也可以使用JIT編譯。不信的可以看看.NET的C++編譯器。
到最后的時(shí)候,速度并不重要。電腦浪費(fèi)了大部份時(shí)間在等待用戶輸入。
速度仍然很重要。我仍然在等我的筆記本啟動(dòng)起來,我在等我的編譯器停下來,我還要等Word打開一個(gè)超長的文檔。
我在一個(gè)金融公司工作。有時(shí)候我必須對一個(gè)很大的數(shù)據(jù)集進(jìn)行模擬。速度在這種情況下都很重要。
有些JIT可以在棧上分配一些對象。
當(dāng)然,一些。
你的轉(zhuǎn)換代碼看起來很丑??梢栽陬惖睦^承層次上檢查類。
首先,這樣只比矩陣查找快一點(diǎn)點(diǎn)而已。
第二,這樣只能查找類,類只占多少?低層次的細(xì)節(jié)往往是通過接口來實(shí)現(xiàn)的。
哈,那么我們都應(yīng)該使用匯編?
不是的,我們都要使用對業(yè)務(wù)有用的語言。Java提供了龐大的標(biāo)準(zhǔn)庫,讓很多任務(wù)變得容易,因此Java是偉大的。它比其它所有的語言更容易移植(但并非100%可移植——不同的平臺有不同問題)。它具有垃圾收集機(jī)制,簡化了內(nèi)存管理,同時(shí)也讓某些構(gòu)造如閉包可實(shí)現(xiàn)。
但是,同時(shí),Java和所有的語言一樣,也有瑕疵。在值語義的類型上缺少支持。它的同步并不是很有效率。它的標(biāo)準(zhǔn)庫建立在異常檢查之上,把實(shí)現(xiàn)拖進(jìn)了接口。它的性能可以更好。它的數(shù)學(xué)庫有些惱人的問題。諸如此類。
這些缺憾都是大問題嗎?看你用它做什么。因此,在幾種語言里,連同它的編譯器以及可以選擇的類庫里選擇對你的工程有利的一種。
回復(fù) 更多評論
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???[未登錄]
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
2008-12-08 21:38 | murainwood
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???[未登錄]
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???[未登錄]
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???
2011-08-10 09:27 | 嗷嗷嗷
還是那句話,你下結(jié)語評論的時(shí)候,不要忘記前提。
如果在微觀上面講,做一個(gè)應(yīng)用,java的每次損耗是6ms,而C++是2ms,那么這是看不出來,在人的感覺也不明顯,因而判定Java不必C++慢。
但從宏觀上面來講,如果你的應(yīng)用是幾百萬 上千萬的量,那么這些積累起來就是比較大的損耗了。這就是Java為什么通常應(yīng)用集群技術(shù)等等。
而且一味的擴(kuò)大內(nèi)存也有瓶頸,為什么,在桌面級別應(yīng)用上面,如windows上面會(huì)page內(nèi)存到磁盤,別忘了 實(shí)際磁盤速度這10幾年其實(shí)并沒有太多變化,仍然大大跟不上內(nèi)存,所以一般太大的程序,長時(shí)間不使用,一旦最大化,就要等待很久時(shí)間。比如游戲等等。
其實(shí)要說Java慢,并非語言本身,而是不同的機(jī)制。這么多年Java在算法上面改進(jìn)了多少?可是本身硬傷是不可能有太多改變的,所以只能靠機(jī)器的提升。如果你是C++程序員,你要掌握比Java更多的處理內(nèi)存的方法和技術(shù),帶來的是可以稍微低端的計(jì)算機(jī)可以跑。
回復(fù) 更多評論
如果在微觀上面講,做一個(gè)應(yīng)用,java的每次損耗是6ms,而C++是2ms,那么這是看不出來,在人的感覺也不明顯,因而判定Java不必C++慢。
但從宏觀上面來講,如果你的應(yīng)用是幾百萬 上千萬的量,那么這些積累起來就是比較大的損耗了。這就是Java為什么通常應(yīng)用集群技術(shù)等等。
而且一味的擴(kuò)大內(nèi)存也有瓶頸,為什么,在桌面級別應(yīng)用上面,如windows上面會(huì)page內(nèi)存到磁盤,別忘了 實(shí)際磁盤速度這10幾年其實(shí)并沒有太多變化,仍然大大跟不上內(nèi)存,所以一般太大的程序,長時(shí)間不使用,一旦最大化,就要等待很久時(shí)間。比如游戲等等。
其實(shí)要說Java慢,并非語言本身,而是不同的機(jī)制。這么多年Java在算法上面改進(jìn)了多少?可是本身硬傷是不可能有太多改變的,所以只能靠機(jī)器的提升。如果你是C++程序員,你要掌握比Java更多的處理內(nèi)存的方法和技術(shù),帶來的是可以稍微低端的計(jì)算機(jī)可以跑。
回復(fù) 更多評論
# re: 一點(diǎn)小感想:為什么那么多人說Java慢???[未登錄]
只有注冊用戶登錄后才能發(fā)表評論。 | ||
![]() |
||
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
|
||
相關(guān)文章:
|
||
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
30 | 1 | 2 | 3 | 4 | 5 | 6 | |||
7 | 8 | 9 | 10 | 11 | 12 | 13 | |||
14 | 15 | 16 | 17 | 18 | 19 | 20 | |||
21 | 22 | 23 | 24 | 25 | 26 | 27 | |||
28 | 29 | 30 | 31 | 1 | 2 | 3 | |||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
如果真的給你一片天,你敢不敢要?
常用鏈接
留言簿(3)
隨筆分類
隨筆檔案
- 2007年6月 (3)
- 2007年1月 (1)
- 2006年11月 (1)
- 2006年10月 (6)
- 2006年9月 (1)
- 2006年8月 (2)
- 2006年7月 (8)
- 2006年6月 (1)
- 2006年5月 (3)
- 2006年4月 (4)
相冊
搜索
最新評論

- 1.?re: 一點(diǎn)小感想:為什么那么多人說Java慢???[未登錄]
- 評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
- --夏
- 2.?re: 一點(diǎn)小感想:為什么那么多人說Java慢???[未登錄]
-
莫名被最后一句話戳中笑點(diǎn)@fjchenq
- --aa
- 3.?re: 一點(diǎn)小感想:為什么那么多人說Java慢???
- 評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
- --嗷嗷嗷
- 4.?re: 一點(diǎn)小感想:為什么那么多人說Java慢???[未登錄]
- c++存在一個(gè)函數(shù)表,訪問一段代碼至少要訪問兩次內(nèi)存,所以在對性能要求很高的操作系統(tǒng)內(nèi)核上不適宜使用
- --光光
- 5.?re: 一點(diǎn)小感想:為什么那么多人說Java慢???
- Java桌面應(yīng)用慢到死!垃圾一樣的東西
- --的