看板 Soft_Job 關於我們 聯絡資訊
※ 引述《Aurim (Who cares?)》之銘言: : ※ 引述《lgd1008 (lgd1008)》之銘言: : : Java效能的瓶頸多在I/O, 資料需要頻繁地進出VM, marshalling. 為了I/O效能, 你可以 : : 使用JNI, JNI本來就是Java考量所在; 相反的,若為了彈性或簡潔, 你也可以在Java裡執行 : : Java Script. 這些東西都提供你做選擇. : 那只是一個比較明顯的瓶頸,個人看法是Java永遠也快不起來。 : : 為什麼?因為Java常態是編譯成bytecode給VM跑,VM再做JIT轉成原生碼給CPU跑, : 永遠有一個overhead在。即使JIT美妙到可以有直接編譯成原生碼給CPU跑的效能的95%, : 差那5%代表的是什麼?代表在同一時脈下,Java就是跑輸直接編譯成原生碼的東西5%。 : CPU時脈愈快,那5%換算出來的絕對差距也就愈大。何況現實應用中,從來也沒只差5%。 : ================================= Java VM 是建立在 Stack Machine 的架構上, 同 High Level Language Direct Execution Machine 是同一類的構想, 但高階語言直接執行不容易很高效用硬體 做到, 所以就分層建立在中間碼的抽象機器裡. 這也符合程式語言編譯的過程. 使用 stack 是因為很多高階語言的敘述, 在前後次序的出現上有塊狀(block) 的開始結束, 如同左右括弧的作用, stack 因為先天就隱含著事件的前後歷史資 訊在結構裡, 所以處理這種塊狀是很能對應的. 這種架構以硬體實現的早期商用 機器就是 HP3000 Stack Machine, 不過, 東西一旦做死硬了, 就是沒彈性, 也 就退回一直留在軟體模擬的 VM 裡進行實驗開發. 但這個進展, 在早期也影響了 微處理器開始支援很基本的 call/return stack 操作指令. 而傳統的電腦多數 是 register based architecture. 並沒有 stack 這種可運用的暫存空間. ====== "因為Java常態是編譯成bytecode給VM跑,VM再做JIT轉成原生碼給CPU跑,永遠有 一個overhead在". ====== 這個說法的問題在目前的技術並不存在每此次都要對反覆執行 段做 JIT 轉換的時耗問題, 因為轉一次後就已能對整段重覆再用. 理論上是能完 全逼近 傳統 compiler 相對於 interpreter 避免重覆解譯辨識的效果. 問題的實況之一是: 最低層的 CPU 是用 native code 在模擬 stack machine 的 架構動作把要的動作做出來, 模擬的當然不如直接用 Stack Machine硬體(就是可 以多路平行)直接執行. 也就不如 compiler 是把中間碼直接對應在 register based architecture 硬體上用其硬體直接執行. Java JIT 只是快速把中間碼換成底層 CPU 的機器碼動作, 不必再重覆做軟體的 解譯辨識而能整段再用. 對 interpreter 言, 效率是變高, 但並沒有把 stack (flying register) architecture 的中間結果 在stack來回動態移動 使用記憶 體代替 register 的耗時現象, 整個換成底層 cpu 擅長的 多個register 借用 暫存與多途徑快速搬移的優點. 把 java stack architecture 換成 register based architecture. 對 bytecode 轉換時, 若針對底層的硬體來對應利用, 就很可能可脫開 stack architecture 欠 缺專用硬體支援的缺點. 而這也是傳統 compiler 的強項. 這種做法, 有VM的優點(中間碼), 也有 compiler 針對 hardware architecture optimization 的長處, 是值得思考的特點. 如果真能達成, 那就能逼近其他同類 程式語言利用 compiler 的效果.
francej:現實是,平均來看Java並沒有逼近C的效能. 不然Google也不用 05/27 18:47
francej:去搞甚麼NDK了. android上的瀏覽器也可以純用java寫就好啦 05/27 18:48
TonyQ:要看什麼東西上有沒有逼近C的效能... 05/27 22:04
Lordaeron:有什麼事可以逼近C 的效能嗎? 05/27 22:07
TonyQ:有些地方上C也快不起來(ex. 大量 Q db 很多次) etc 05/27 22:39
TonyQ:效能瓶頸卡在別的事情上,而不是語言上的時候。 05/27 22:39
TonyQ:當然,你可能可以找到一個方法去優化他,但那又牽扯成本問題 05/27 22:40
Lordaeron:快慢是相同的,但query db 的問題若在量,則和lang 無關 05/27 22:53
Lordaeron:但若是concurrent 的response,則java 是輸到脫褲 05/27 22:53
Lordaeron:若是大到了大量的資料回傳, 也是C 大勝 05/27 22:57
Java 是 OO 而且是 stack machine. 對比上就是 C++/C 若就 compiler 的角度言, 中間碼依賴 stack machine architecture 來翻譯處 理是合理的, 因為 stack operation 可方便辨識 grammar. 從中間碼的 bytecode 要再轉換為 native machine code 時, 一個做法是讓下 層的 CPU 模擬 stack machine 用下層指令去完成 stack machine 的動作, 這 是目前 Java 的做法. 另一個做法是把 bytecode 指令轉換為 register based architecure, 用下層 cpu 的多個 architecture register 代替stack , 利用 多register指令 完成 bytecode指令 同樣功能的動作. 現在想這樣做的就是 Dalvik VM. 這想法也就是傳統 compiler 後段的行為. 理論上是同類的轉換與 最佳化, 若不限 Just In Time 的限時想法, 改用 compiler 轉成 native code 就逼近 傳統 C/C++ 的做法. Java bytecode 可以跨網路執行, 所以傳送跨網路的資訊不用 pointer reference 這是其優點也是限制, 但在同一個機器執行時, compiler 可以配合同一機器內用 shared memory 架構最佳化執行, 這也就逼近傳統 C 的優點, 但使用者仍然是不 能任意使用到 pointer.
Lordaeron:給個逼近的定義吧,例如C 的速度打9折, 打8折,還是打7折 05/28 09:36
Lordaeron:否則, 逼近?各有心裏的想法, 各說各話就不好了. 05/28 09:37
同類同性質的東西, 才有比較的基礎, 要雞跟鴨比游泳, 那是怎麼比? C 語言要依靠 compiler 來最佳化, 若要跟寫組語的專業者比, 那也是有所不及. 譬如 OS 的 ISR 與 Dispatcher 還是常用組語, 因為簡單又高效, C 又不觸及 能指定那個 register 來更動, 當然是難能也就不如. 但拋開這些特殊之處, 要處理高階資料結構跟複雜計算, C 是不是能逼近組語寫 成的這些動作的效果? C compiler 跟 ASM programmer 都假設底層是 register based architecture. 制式翻譯的編譯器, 若以跟 programmer 同樣思考的算法 去做決選, 是不是就能逼近 programmer 以組語寫成的程式效率?
Lordaeron:你扯開這個幹嘛,你就用相同的東西,來比,什麼叫逼近就好 05/28 11:20
這道題是 Java 效能, 跟 java 同類的來比, 才知所差異與改進. 若說 Java 與 C 都是程式語言, 就如同男人與女人都是人, 男人通常比女人 力大跑得快, 但男人無法懷孕生小孩, 那女人比誰能懷孕就讓力大跑快沒意 義了. Java 可以 portable 可以下載 bytecode 就立即執行, 這是目前的 C/C++ 做不到的. 程式語言的翻譯用 stack 協助會很方便, 但最終的執行目前多數環境並沒有 stack 硬體協助, 這個末段執行的效率在動作上就 register based 的 cpu 言是難以做 code optimization. 就如同 Davik VM 是針對 Register based 做利用改進可以減少 native code 指令數, 減少搬移, 相對於 Java VM 在 x86 可以提速 26%, 但 bytecode 本身就是 stack base 欠缺為 register based 的硬體架構保留某些可進一步再共用化減的資訊, 目前是基於相容性 而不更改 bytecode, 所以理論上不全然是以 register base 為考量, 在效 能上比起全以 register base 考量的做法就是會有所不及. 但若基於 register base 為思考, 那這個女人若拿掉子宮與哺乳的作用就會 逼近男人, 也就能改成力大快跑的作用, 一切就可跟男人來比, 但可能也就不 成為女人了. 可是, 全世界會因需要而讓力小慢跑的女人存在.
Lordaeron:重點: 什麼叫逼近? 什麼樣的程式Java 逼近C 05/29 13:34
Lordaeron:當然也加一下, 什麼樣的情況. 05/29 13:34
Lordaeron:別說register based了,各CPU 的register 用法及數量完 05/29 13:35
Lordaeron:全不同. 我只想知什麼樣的程式在什麼樣的情況下,可以 05/29 13:35
Lordaeron:讓java 多"逼近" C. 05/29 13:36
把程式 editing,下載到另一台機器,compiling,linking,load&go看何者先跑起來, (還不用搬 compiler 過去)就知何者快. Java 是stack machine, 全都是以 stack 運作為主的動作程式, 就會逼近 C 編出 來的程式, 若是在 register 與記憶體 都很少的 CPU 上跑很多臨時變數與不同常 數的程式, C 就會佔不到太多便宜.
GALINE:我還是覺得只談「JVM做了哪些優化」以及「Java有多少的原罪 05/29 18:54
GALINE:overhead」是見樹不見林的事情...根本沒人知道原文作者的系 05/29 18:55
GALINE:統到底規格如何需求如何...XD 05/29 18:55
GALINE:論戰變成「Java絕對沒問題」跟「Java絕對做不到」的選邊戰 05/29 18:59
GALINE:整個很微妙,雖然原po公司裏面的 profiling 數字大概我們也 05/29 18:59
GALINE:沒機會看到,所以只好自己想像的很開心之類的... 05/29 19:00
GALINE:而且以原po的工作內容來說,我知道某些單位是連 array 05/29 19:01
GALINE:iteration 的時間都在省,在這種情況下建立物件可是非常貴 05/29 19:02
原post的問題, littlethe 的回貼已經很實際的講到了. 至於資深經理或工程師, 他們有其經驗與產品的角度需求, 自然有其看法. software license 與 bytecode 可還原出 source 程式及容易亂抄亂改 是他們的首要顧忌. 他們考慮的跟效能未必就完全相關! 若談VM 最主要的是相容與簡便, 效能則是該努力的目標, 但從來就不是最高訴求. VM 可以輔助出新架構以協助出新設計的硬體加速與指令, 但語言的VM都以方便針 對用途為訴求. ※ 編輯: ggg12345 來自: 140.115.5.14 (05/29 19:21)
GALINE:我倒覺得不相干耶[汗] 結構化可以讓程式開發者容易掌握程式 05/29 19:36
GALINE:沒錯,但是並不是一定要靠物件才能夠寫出結構化的程式。 05/29 19:37
GALINE:更何況以原 PO 第2篇文的內容來判斷,他們公司的產品是極端 05/29 19:37
GALINE:要求效能的東西。確實有可能光是物件產生的 overhead 就超 05/29 19:38
GALINE:他們需求。當然這也要看他們應付的是哪個等級的流量,而這 05/29 19:39
GALINE:點板上應該不太可能有其他人知道 XD 05/29 19:40
GALINE:至於如何不要使用物件卻又能寫出結構化的程式,又甚至是如 05/29 19:42
GALINE:果不用物件為何要用Java當作後端,這些又是各自不同的問題 05/29 19:43
GALINE:另外一個跟JVM本身實作有關的問題是,如果流量很大,大量的 05/29 19:45
GALINE:小物件產生/消滅可能會導致大量的記憶體裂片。這種狀況輕則 05/29 19:46
GALINE:GC狂跑卡住程式,重則帳面上記憶體充足卻還是拋出Out Of 05/29 19:47
GALINE:Memory error.... 05/29 19:47
GALINE:我個人的認定是,沒有spec跟profiling的話,沒人有答案 05/29 19:48
Lordaeron:就算profiling 除非你大改, 否則也是一樣 05/29 20:04
GALINE:那就要看出來結果如何了,又是一個只有當事人知道的問題 05/29 20:05
Lordaeron:結果如何都好,你要能擔下後來,還要說服上司,才有可能改 05/29 20:16
Lordaeron:而且改好,不見得是功一件,但沒改好絕對是過一個 05/29 20:16
GALINE:所謂的政治問題 XD 05/29 20:17
Lordaeron:做事本來就人的問題比較多. 05/29 20:19
GALINE:是說這個提問我覺得光技術層面就太多不確定因素了,以原po 05/29 20:20
GALINE:文章內容,看不出來到底他們需要壓榨效能到什麼程度... 05/29 20:22
Lordaeron:要高效能,不要往java想,這是基本的道理 05/29 20:28
GALINE:所以我好奇為何要用Java當後端 XD 不過我記得有看過一些例 05/29 20:30
GALINE:子是Java的速度(在JVM已經載入的狀況下)可以跟C++一拼 05/29 20:31
GALINE:或許,也許,在小心適當的最佳化下,Java的程式可以跟原生 05/29 20:32
GALINE:程式一拼 05/29 20:32
GALINE:也不排除這就是為什麼原po的長官這麼龜毛,但是我還是想不 05/29 20:33
GALINE:通那一開始幹嘛要選用 Java XD 05/29 20:33
Lordaeron:執行速度, 不是起動速度, 這是兩回事. 05/29 21:46
Lordaeron:用java,花2萬就有人了,用java,寫程不會哪麼容易當 05/29 22:59
Lordaeron:用java ,君不見一堆cert 的高手. 用java 可以隨便換人 05/29 23:00
Lordaeron:用java可以跟賣硬體的抽點頭 05/29 23:00