簡體   English   中英

Java 性能:關於使用 Long.valueOf(..)

[英]Java Performance: regarding using Long.valueOf(..)

我們經常使用Long.valueOf()進行相同的字段轉換。 所以這沒關系,或者我們需要將轉換的值存儲在其他字段中然后使用。 示例:我們在 String 中接收特定的 id,無論我們在哪里使用,我們每次都執行 Long.valueOf(id)。

喜歡 :

void methodName(String id) {
//some code
... = Long.valueOf(id);
....
....
callOtherMethod(Long.valueOf(id));
....
...
map.put("urId", Long.valueOf(id));
....
}

當我們考慮性能和所有這些時,這可以嗎? 別的

這個很好去

喜歡 :

void methodName(String id) {
//some code
Long longId = Long.valueOf(id);
... = longId;
....
....
callOtherMethod(longId);
....
...
map.put("urId", longId);
....
}

哪一個最好,為什么(如果你能解釋一下)?

我個人贊成不要多次重復相同的操作。 所以我更喜歡你的第二種方法。

在編程時,多次編寫的同一段代碼通常是難聞的,如果您可以提取重復的代碼段以供重用,例如將重復的塊提取到參數化方法中,或者在這種情況下分配Long.valueOf(id)的輸出Long.valueOf(id)到一個變量,您可以避免變得難以閱讀的冗長代碼。

如果您從Long.valueOf() (或任何其他方法)返回的值應該Long.valueOf()使用,則使用第二種方法總是更好。 因為在本地存儲它總是比再次計算更便宜。

對於有問題的示例,不難計算與 JMH 的性能差異。 我創建了可以計算這個的小基准:

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 10)
@Fork(1)
@State(Scope.Thread)
public class ValueOfPerfTest {

    @Param({ "1000" })
    private String number;

    @Param({ "10", "20", "30"})
    private long tokens;

    @Benchmark
    public void cachedValueOf(Blackhole blackhole) {
        Long l = Long.valueOf(number);

        // three times using the consume
        blackhole.consume(l);
        blackhole.consume(l);
        blackhole.consume(l);

        Blackhole.consumeCPU(tokens);
    }

    @Benchmark
    public void nonCachedValueOf(Blackhole blackhole) {
        // three times using the consume
        blackhole.consume(Long.valueOf(number));
        blackhole.consume(Long.valueOf(number));
        blackhole.consume(Long.valueOf(number));

        Blackhole.consumeCPU(tokens);
    }

    @Benchmark
    public Long valueOf(Blackhole blackhole) {
        Blackhole.consumeCPU(tokens);

        return Long.valueOf(number);
    }

    @Benchmark
    public void baseline(){
        Blackhole.consumeCPU(tokens);
    }

}

我不想在這里詳細說明 JMH,但主要區別在於nonCachedValueOf調用了Long.valueOf() 3 倍,而在緩存版本中只調用了 1 次。 我的期望是非緩存版本會慢 3 倍,這基本上是結果顯示的內容:

 [java] Benchmark                                   (number)  (tokens)  Mode  Samples    Score   Error  Units
 [java] i.n.a.p.ValueOfPerfTest.baseline                1000        10  avgt       10   11.238 ± 0.387  ns/op
 [java] i.n.a.p.ValueOfPerfTest.baseline                1000        20  avgt       10   30.392 ± 0.668  ns/op
 [java] i.n.a.p.ValueOfPerfTest.baseline                1000        30  avgt       10   50.217 ± 1.101  ns/op
 [java] i.n.a.p.ValueOfPerfTest.cachedValueOf           1000        10  avgt       10   37.368 ± 2.035  ns/op
 [java] i.n.a.p.ValueOfPerfTest.cachedValueOf           1000        20  avgt       10   54.614 ± 3.847  ns/op
 [java] i.n.a.p.ValueOfPerfTest.cachedValueOf           1000        30  avgt       10   74.412 ± 2.474  ns/op
 [java] i.n.a.p.ValueOfPerfTest.nonCachedValueOf        1000        10  avgt       10   82.329 ± 2.649  ns/op
 [java] i.n.a.p.ValueOfPerfTest.nonCachedValueOf        1000        20  avgt       10  100.595 ± 2.476  ns/op
 [java] i.n.a.p.ValueOfPerfTest.nonCachedValueOf        1000        30  avgt       10  118.715 ± 3.277  ns/op
 [java] i.n.a.p.ValueOfPerfTest.valueOf                 1000        10  avgt       10   35.815 ± 0.766  ns/op
 [java] i.n.a.p.ValueOfPerfTest.valueOf                 1000        20  avgt       10   53.074 ± 3.942  ns/op
 [java] i.n.a.p.ValueOfPerfTest.valueOf                 1000        30  avgt       10   73.378 ± 2.318  ns/op

如果您對結果進行更深入的挖掘,如果您排除基線(這里有 30 個標記),您會得到大約以下結果:

[java] i.n.a.p.ValueOfPerfTest.cachedValueOf       24,195 ns/op
[java] i.n.a.p.ValueOfPerfTest.nonCachedValueOf    68,498 ns/op
[java] i.n.a.p.ValueOfPerfTest.valueOf             23,161 ns/op

很明顯,幾乎慢了 3 倍。

關於每次使用 Long.valueOf 創建任何新對象的問題? , 如果數字不在緩存中,答案是肯定的。 java 有“常用值”的緩存,默認情況下,從 -128 到 127 的數字都有緩存。但可以通過使用-XX:AutoBoxCacheMax來增加-XX:AutoBoxCacheMax JVM 選項。

暫無
暫無

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

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