寫java代碼的時(shí)候突然想到的奇怪問(wèn)題:
有一個(gè)函數(shù)很大,所以把一個(gè)大程序分成好多個(gè)小邏輯很正常,比如這樣的
public void 把大象關(guān)進(jìn)冰箱(大象){ 檢查大象狀態(tài); 檢查冰箱狀態(tài); 打開(kāi)冰箱; 檢查冰箱大??; 把大象放進(jìn)去; 檢查異常 關(guān)上冰箱; 清除中間數(shù)據(jù); }
變成下邊這樣:
public void 把大象關(guān)進(jìn)冰箱(大象){ 打開(kāi)冰箱(); 把大象放進(jìn)冰箱(); 關(guān)上冰箱(); } protect 冰箱 打開(kāi)冰箱(){ ... } protect boolean 把大象放進(jìn)冰箱(){ ... } protect 冰箱 關(guān)上冰箱(){ ... }
這種方式大函數(shù)調(diào)小函數(shù)(向上邊這樣)的方式會(huì)讓程序在jvm上跑的速度變慢嗎?不知道我描述的清楚嗎?
不過(guò)在 Haskell 里面函數(shù)調(diào)用幾乎是 0 成本的,所以函數(shù)粒度可以寫的特別小。
會(huì),因?yàn)閏ontext切換了,不過(guò)這種一般忽略,得保證代碼可讀性
你說(shuō)的,這些是不定的,因?yàn)閷?duì)于程序的優(yōu)化問(wèn)題本質(zhì)上是一個(gè)不可判定的問(wèn)題。舉個(gè)例子,如果從調(diào)用的角度而言,好像是增加了開(kāi)銷,但如果另一個(gè)方面,我們可以把程序分解成很多的線程進(jìn)行執(zhí)行,可能速度又會(huì)加快,而且,變成小代碼了,cache的優(yōu)化可能會(huì)使其加快,(這個(gè)要取決于你的循環(huán)結(jié)構(gòu)體),有很多因素會(huì)影響你的代碼運(yùn)行,但當(dāng)前,是以程序員的開(kāi)發(fā)為核心進(jìn)行優(yōu)化,也就是怎么讓程序員更有工作效率,怎么來(lái)。分解成小代碼,顯然是有利于程序員開(kāi)發(fā),從這個(gè)角度說(shuō),你其實(shí)已經(jīng)優(yōu)化了代碼了。
方法的調(diào)用是有成本的,但是其對(duì)性能的影響可以忽略。值得一提的是,Java編譯器幾乎不會(huì)對(duì)這些調(diào)用進(jìn)行優(yōu)化,但是JVM在運(yùn)行時(shí)會(huì)去分析,然后選擇性將一些方法調(diào)用進(jìn)行內(nèi)聯(lián),以達(dá)到節(jié)省開(kāi)銷的目的。程序員在非極端要求性能的情形下不必關(guān)心這些細(xì)節(jié)。
可能會(huì)變得慢,但是不是關(guān)鍵。關(guān)鍵是你的思路和代碼實(shí)現(xiàn)過(guò)程是不是最優(yōu)。
所以C++里有內(nèi)聯(lián)函數(shù)。因?yàn)楹瘮?shù)調(diào)用會(huì)復(fù)制參數(shù),使用堆棧和代碼跳轉(zhuǎn)。。。。