国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

在什么情況下,Java比C++慢很多?

瀏覽:80日期:2022-09-06 08:10:40

問:在什么情況下,Java 比 C++ 慢很多?

答:Ben Maurer:

為了回答這個(gè)問題,需要先將該問題分成幾個(gè)可能引起慢的原因:

垃圾回收器。這是一把“雙刃劍”。如果你的程序遵循“大部分對(duì)象都在年青代中消亡”模型,垃圾回收器是非常有利的(很少的碎片,更好的緩存局部性)。但是,如果程序不遵循該模型,JVM將花費(fèi)很多資源來(lái)回收堆內(nèi)存。

大對(duì)象。在Java中,所有的對(duì)象都有一個(gè)vtable指針,而C++中使用POD結(jié)構(gòu)沒有額外開銷。此外,所有的Java對(duì)象是可以被鎖定的。其實(shí)現(xiàn)依賴于JVM,這可能需要在對(duì)象中增加額外的字段。大對(duì)象 == 緩存更少的對(duì)象 == 更慢。(另一方面,Java 7 用64位記錄壓縮后的指針,這也是造成該問題的一部分原因。

缺乏內(nèi)聯(lián)對(duì)象。在Java中,所有的類都是指針。在C++中,對(duì)象可以和其它對(duì)象一起分配,或者在棧上分配。這樣可以提高緩存的局部性,從而減少動(dòng)態(tài)內(nèi)存分配的開銷。

平臺(tái)函數(shù)調(diào)用。在Java中,JNI的調(diào)用或者將對(duì)象編譯成本地代碼都會(huì)帶來(lái)不小的開銷。如果你需要頻繁調(diào)用客戶端的C++代碼,會(huì)增加很大的開銷。

低效的強(qiáng)制抽象。例如,在Java中字符串是不可變的。如果你想寫一個(gè)XML分析器,你只使用String對(duì)象(沒有char[]),它將會(huì)很慢,因?yàn)樾枰峙漕~外的空間。

虛函數(shù)調(diào)用增加。JVM中,幾乎所有的函數(shù)調(diào)用都是虛函數(shù)調(diào)用。有許多代碼嘗試避免虛函數(shù)調(diào)用,但是很多場(chǎng)景下,JVM無(wú)法解決這個(gè)問題。這阻礙了代碼的內(nèi)聯(lián),使代碼變慢。

缺乏高級(jí)的編譯特征及轉(zhuǎn)為匯編的能力。 如果你寫了一段能從匯編得益的代碼Java可能表現(xiàn)不佳。

在我看來(lái),最大的問題是垃圾回收。在程序中,強(qiáng)制在大的內(nèi)存中進(jìn)行多次完全GC,是最容易導(dǎo)致Java和C++之間產(chǎn)生鴻溝的原因之一。除此之外,如果將程序的工作集放在L2緩存之外,像大對(duì)象、缺乏內(nèi)聯(lián)對(duì)象等問題,也會(huì)導(dǎo)致兩者之間的巨大差別。

低效的強(qiáng)制抽象和平臺(tái)函數(shù)也會(huì)導(dǎo)致速度下降,但是這通常只會(huì)因?yàn)榈图?jí)的代碼才會(huì)產(chǎn)生。如果你使用寫得很好的Java代碼庫(kù),這通常不是什么大問題。

答:Todd Lipcon

我基本同意Ben Maurer(hey Ben!)的回答。有幾個(gè)小點(diǎn)不同:

在最新的JVM中,當(dāng)這種分配永遠(yuǎn)不會(huì)從(a)局部函數(shù)或(b)局部線程逃逸出去的時(shí)候,逃逸分析能有效地決定一種固定分配。也就是說(shuō)當(dāng)分配不需要加鎖,通常是在自身的棧空間上進(jìn)行的。這兩種情況下都是一種簡(jiǎn)單的“指針碰撞(bump the pointer)”分配,這等同于C中的棧分配。

譯者注:

逃逸分析 Escape Analysis,是一種編譯優(yōu)化技術(shù),指分析指針動(dòng)態(tài)范圍的方法。通俗地說(shuō),當(dāng)一個(gè)對(duì)象的指針被多個(gè)方法或線程引用時(shí),我們稱這個(gè)指針發(fā)生了逃逸。指針碰撞(bump the point)。假設(shè)Java堆中內(nèi)存是絕對(duì)規(guī)整的,所有用過的內(nèi)存都被放在一邊,空閑的內(nèi)存被放在另一邊,中間放著一個(gè)指針作為分界點(diǎn)的指示器,那所分配內(nèi)存就僅僅是把那個(gè)指針向空閑空間那邊挪動(dòng)一段與對(duì)象大小相等的距離,這種分配方式稱為“指針碰撞”。

即使沒有逃逸分析,年青代的分配也是通過指針碰撞方式,在線程本地分配緩沖區(qū)(TLAB)中完成的,不需要進(jìn)行同步。所以Java中小對(duì)象的分配有的時(shí)候比C語(yǔ)言實(shí)現(xiàn)的 malloc() 方式更快。更好的 malloc 方法像Google的 tcmalloc,采用了類似的方式。但是由于C語(yǔ)言無(wú)法在內(nèi)存中對(duì)分配后的對(duì)象重新分配,所以某些方面會(huì)受到限制。

雖然存在內(nèi)聯(lián)和虛函數(shù)問題,但是實(shí)際上,Java在某些情況下甚至可以做的比C更好。特別是,C不能通過動(dòng)態(tài)鏈接功能來(lái)實(shí)現(xiàn)內(nèi)聯(lián),因?yàn)閮?nèi)聯(lián)是在編譯時(shí)期進(jìn)行的,而不是運(yùn)行時(shí)期。而Java可越過不同的類或庫(kù)的邊界來(lái)動(dòng)態(tài)內(nèi)聯(lián)一個(gè)函數(shù),即使該類的真正實(shí)現(xiàn)在編譯期間還不可用。許多工作中,這種方式比C++的虛函數(shù)調(diào)用更有效,C++虛函數(shù)調(diào)用總是需要調(diào)用虛表。而JIT編譯器,如果之前動(dòng)態(tài)屬性已經(jīng)丟失(如新的類已經(jīng)被加載),能夠聰明地取消內(nèi)聯(lián)優(yōu)化。

新版本的GCC提供一些這方面優(yōu)化,稱為“全程序優(yōu)化”或“鏈接時(shí)優(yōu)化”(http://gcc.gnu.org/wiki/LinkTime…),允許在工程范圍內(nèi)越過對(duì)象文件進(jìn)行內(nèi)聯(lián)。但是,基本上還是不允許通過動(dòng)態(tài)鏈接的方式來(lái)實(shí)現(xiàn)內(nèi)聯(lián)(如通過內(nèi)聯(lián)的方式實(shí)現(xiàn)zlib的調(diào)用等)。許多大型項(xiàng)目都是通過復(fù)制標(biāo)準(zhǔn)庫(kù)的功能到它們的代碼中來(lái)實(shí)現(xiàn)。

原文鏈接: quora 翻譯: ImportNew.com

標(biāo)簽: Java
主站蜘蛛池模板: 欧美一级毛片免费大片 | 亚洲高清国产拍精品影院 | 亚洲欧洲日产v特级毛片 | 精品国产免费一区二区三区五区 | 亚洲精品久久久成人 | 亚洲黄网址 | 日本九九视频 | 亚州不卡 | 国产精品日韩专区 | 最近中文字幕精彩视频 | 久久久久久综合成人精品 | 亚洲免费视频在线 | 手机看片亚洲 | 欧美一区二区日韩一区二区 | 欧美a在线 | 特级一级毛片免费看 | 夜夜春夜夜夜夜猛噜噜噜噜噜 | 国产黄页 | 亚洲视频在线观看 | 久久国产精品-久久精品 | 欧美精品18videos性欧美 | 亚洲综合第一区 | 成人禁在线观看午夜亚洲 | 亚洲高清国产一区二区三区 | 亚洲在线视频观看 | hd最新国产人妖ts视频 | 日本韩国三级在线 | 免费观看一级特黄三大片视频 | 欧美国一级毛片片aa | 国产精品久久久久久影视 | 在线观看 一区 | 国产丝袜不卡一区二区 | 97超级碰碰碰碰在线视频 | 欧美人拘一级毛片 | 亚洲国产一 | 欧美一级欧美一级在线播放 | 美女张开腿双腿让男人桶 | chinese耄耋70老太性 | 尤物tv已满18点击进入 | 99在线视频网站 | 国产成人cao在线 |