2013-04-20 40 views
6

我有這個疑問很多次,但沒弄明白正確soltion。這次我想清除它。我有類似哪一個是在調用函數更好:兩次或存放在變量的結果呢?

1. 
String sNumber="ksadfl.jksadlf"; 
if(sNumber.lastIndexOf('.')>0) 
    //do something 
... 
... 
if(sNumber.lastIndexOf('.')>1) 
//do something 
... 

2. 
int index = sNumber.lastIndexOf('.'); 
if(index>0) 
//do something 
... 
... 
if(index>1) 
//do something 
... 

什麼是第一種方式和第二種方式之間的權衡?哪一個更好地將結果存儲在一個變量中或者兩次調用該函數?

+1

ofcourse存儲結果。 – 2013-04-20 04:49:34

+0

@siva:如果發佈的答案已清除您的疑惑,請接受此答案。 – 2013-04-20 05:25:02

+0

這實際上是一個比它看起來更好的問題。存儲某些東西而不是重新計算它似乎是一種明顯的優化,但有一點實際上變得更慢。在這個例子中,這一點無處可見,但它是真實的,但經常被忽略。 – harold 2013-04-20 08:15:48

回答

5

在這個例子中,從性能角度來看,第二種形式更好(在大多數似乎合理的情況下),並且(IMO)更具可讀性。

一般情況下,有一對夫婦權衡的考慮:

  • 是可讀性比效率更重要?
  • 多少錢「性能損失」的是兩次調用該方法對一次?

此外,您還需要考慮方法可能有副作用的情況,以及它是否會在兩次連續調用中給出不同的答案。在這些情況下,調用方法兩次在語義上不同於調用一次並將結果存儲在臨時變量中。


1 - 的index變量使堆棧幀1的字大。通常,這並不重要,但如果代碼是在被調用的深深遞歸方式遞歸方法,即1個額外字乘以一個數量的嵌套調用可能導致StackOverflowError

+0

+1提到可讀性。 IMO經常(但並非總是)最重要的考慮因素。 有時候,如果有問題的電話是「便宜的」,並且你確實想保持短的代碼,那麼你可以通過採取第二種方式來保存一行。 – vitaly 2013-04-20 07:24:14

+0

我只是想說,如果你聲明它是一個私有成員(在這種情況下女巫將作爲一個全局變量),你可以避免在棧中插入索引變量,選擇第二個選項總是更多高效,並且不會更容易地進入StackOverflow – 2013-04-20 08:22:06

+0

@AlessandroRossi - 可能存在問題;例如如果你想在遞歸調用返回後使用該變量......你不能。 – 2013-04-20 15:05:30

2

你的疑惑很明顯。你的第二種方法是好的和高效的。

因爲如果你的字符串變量數據每次都不變,那麼每次都不需要獲取索引。不需要,一次又一次需要使用sNumber.lastIndexOf('.')。當你lastIndexOf()功能運行時,它都會將花費額外的時間和其他資源。

所以,它更好地使用第二個選項,它使您的程序更快,更短。

+0

並非總是如此,這兩個調用可能會被解釋器優化爲一個(儘管我並不是說這是使用第一種方法的原因),而且您在幾分鐘前纔回答問題,不需要急於接受它。此外,可能會發布更好的一個。 – vikki 2013-04-20 05:32:07

+0

@vikki:是的,你是對的。 – 2013-04-20 05:33:43

+0

@vikki這兩個調用如何優化爲一個?我認爲這是一個字符串'sNumber',它是不可變的,可能是這種情況。但是,正如@Ronixus所說,如果這兩個調用之間的字符串發生了變化呢?和'someObject'調用一樣嗎? – siva 2013-04-20 13:33:40

3

由於該問題僅談到2個精益lastIndexOf調用,實際上兩者之間幾乎沒有什麼區別。如果它通過,做了數據庫命中,然後存儲該方法的結果到一個變量會看到你一些改進的代理什麼的遠程調用。

enter image description here

關於再次調用此方法的好處是,您總能獲得該指數的最新值,如果它在早期塊地方操作。在大多數情況下,#2將是正確的選擇,但對於上面的確切示例,它是#1。

+1

好點,但一般來說最好保持sNumber不變。在這種情況下,級聯影響不是問題。 – mikera 2013-04-20 07:41:28

1

你的問題是內存使用和CPU使用率之間的經典折衷。

首先,您必須確定您的程序是否在內存中佔用很小的空間,或者是否希望它快速運行。解決方案1很可能會導致最少的內存使用量(因爲您不存儲int),而解決方案2將導致最快的執行時間,因爲您不必執行兩次indexOf計算。

這就是說,在內存中存儲計算並不總是產生最快的程序。佔用較小的內存通常會導致更少的緩存未命中。緩存未命中通常比簡單地執行兩次計算要慢得多。

要了解最小化緩存未命中的重要性,請參見this文章,其中討論了C++中list與vector的性能。人們會期望列表比矢量快得多,因爲數據不必被複制。然而,列表實現具有更多的隨機訪問數據,因此更多的緩存未命中導致向量更快。

最後,我會建議你衡量兩個解決方案的性能,並確定你最喜歡的內存和CPU使用率的組合。

相關問題