簡體   English   中英

Java - 調用靜態方法與手動內聯 - 性能開銷

[英]Java - calling static methods vs manual inlining - performance overhead

我感興趣的是我是否應該手動內聯在一些性能敏感算法中稱為100k-100萬次的小方法。

首先,我認為,由於沒有內聯,我會產生一些開銷,因為JVM必須確定是否要內聯這個方法(甚至不能這樣做)。

然而,前幾天,我用靜態方法的調用替換了這個手動內聯代碼,並看到了性能提升。 怎么可能? 這是否表明實際上沒有開銷,讓JVM內聯“意志”實際上提升了性能? 或者這在很大程度上取決於平台/架構?

(發生性能提升的示例是使用靜態方法調用swap(int[] a, int i, int j) )替換數組交換( int t = a[i]; a[i] = a[j]; a[j] = t; )) swap(int[] a, int i, int j) 。另一個沒有性能差異的例子是我內聯10個方法,稱為1000000次。)

我見過類似的東西。 “手動內聯”不一定更快,結果程序可能太復雜而無法進行優化分析。

在你的例子中,讓我們做一些瘋狂的猜測。 當您使用swap()方法時,JVM可能能夠分析方法體,並得出結論,由於i和j不會更改,盡管有4個數組訪問,但只需要2個范圍檢查而不是4個。局部變量t是沒有必要的,JVM可使用2個寄存器來完成這項工作,而不涉及R / W的t上堆疊。

之后,swap()的主體被內聯到調用方法中。 這是在上一次優化之后,因此保存仍然存在。 調用者方法體甚至可能已經證明i和j總是在范圍內,因此剩下的2個范圍檢查也被丟棄。

現在在手動內聯版本中,優化器必須立即分析整個程序,變量太多,動作太多,可能無法證明保存范圍檢查或消除局部變量t 在最壞的情況下,這個版本可能需要花費6個以上的內存訪問來進行交換,這是一個巨大的開銷。 即使只有1個額外的內存讀取,它仍然非常明顯。

當然,我們沒有理由認為手動“概述”總是更好,即提取小方法,如願以為它會幫助優化器。

-

我所學到的是,忘記手動微優化。 並不是我不關心微觀性能改進,而是我始終信任JVM的優化。 這是我完全不知道該做什么比做壞事更好。 所以我放棄了。

JVM可以非常有效地內聯小方法。 唯一能夠自我介紹的好處是,如果你可以刪除代碼,即通過內聯來簡化代碼。

JVM在識別這些結構時會查找某些結構並進行一些“手動編碼”優化。 通過使用交換方法,JVM可以識別結構並通過特定優化以不同方式對其進行優化。

您可能有興趣嘗試OpenJDK 7調試版本,該版本可以選擇打印出它生成的本機代碼。

對不起我遲到的回復,但我剛發現這個話題,引起了我的注意。

在Java中開發時,嘗試編寫“簡單而愚蠢”的代碼。 原因:

  1. 優化是在運行時進行的(因為編譯本身是在運行時進行的)。 編譯器無論如何都要弄清楚要做什么優化,因為它不是編譯你編寫的源代碼,而是編譯它使用的內部表示(幾個AST - > VM代碼 - > VM代碼...... - >本機二進制代碼轉換是在JVM編譯器和JVM解釋器的運行時)
  2. 優化編譯器時使用一些通用編程模式來決定優化內容; 所以幫助他幫助你! 編寫一個私有靜態(也許是最終的)方法,它會立即發現它可以:
    • 內聯方法
    • 將其編譯為本機代碼

如果方法是手動內聯的,那么它只是編譯器首先嘗試理解的另一種方法的一部分,並且看是否有時間將其轉換為二進制代碼,或者是否必須稍等一下才能理解程序流程。 此外,根據方法的作用,在運行期間可以進行多次重新JIT:> JVM僅在“預熱”后生成最佳二進制代碼...並且可能在JVM自行升溫之前程序結束(因為我期望最終表現應該非常相似)。

結論:在C / C ++中優化代碼是有意義的(因為二進制轉換是靜態的),但相同的優化通常不會對Java產生影響,因為編譯器JIT是字節代碼,而不是源代碼。 順便說一句,從我看到的javac甚至懶得做出優化:)

然而,前幾天,我用靜態方法的調用替換了這個手動內聯代碼,並看到了性能提升。 怎么可能?

可能JVM分析器在一個地方(靜態方法)比在單獨實施多次時更容易看到瓶頸。

Hotspot JIT編譯器能夠內聯很多東西,特別是在-server模式下,雖然我不知道你是如何得到實際的性能提升的。 (我的猜測是內聯是通過方法調用計數完成的,並且交換這兩個值的方法不會經常調用。)

順便說一句,如果它的性能真的很重要,你可以嘗試這個來交換兩個int值。 (我不是說它會更快,但它可能值得一試。)

a[i] = a[i] ^ a[j];
a[j] = a[i] ^ a[j];
a[i] = a[i] ^ a[j];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM