Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java性能:关于使用Long.valueOf(…)_Java_Performance_Casting - Fatal编程技术网

Java性能:关于使用Long.valueOf(…)

Java性能:关于使用Long.valueOf(…),java,performance,casting,Java,Performance,Casting,我们经常使用Long.valueOf()来进行相同的场浇铸。所以这是可以的,或者我们需要将浇铸值存储在其他字段中,然后使用。 例子: 我们在字符串中接收特定的id,无论在哪里使用,我们每次都执行Long.valueOf(id) 比如: void methodName(String id) { //some code ... = Long.valueOf(id); .... .... callOtherMethod(Long.valueOf(id)); .... ... map.put("urId

我们经常使用Long.valueOf()来进行相同的场浇铸。所以这是可以的,或者我们需要将浇铸值存储在其他字段中,然后使用。 例子: 我们在字符串中接收特定的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);
....
}
这是好的,我们考虑性能和所有这些。否则

这个可以走了

比如:

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()
(或任何其他方法)返回的值应该被多次使用,则最好使用第二种方法。因为存储在本地也比再次计算便宜

对于所讨论的示例,使用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倍,而在缓存版本中只有一次。我的预期是,非缓存版本将慢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个标记),您将得到大约以下结果:

非常清楚,几乎是第三因子


关于您每次使用Long.valueOf创建任何新对象时的问题,如果该数字不在缓存中,则答案为“是”。。java具有“常用值”的缓存,默认情况下,该缓存用于-128到127之间的数字。但是可以通过使用
-XX:AutoBoxCacheMax
JVM选项来增加它。

第二种方法是最好的,因为您可以避免函数调用的
值(…)
是否存在需要修复的性能问题?否则,您应该总是选择可读性最好的代码,这是一个品味和/或项目规则的问题。我更喜欢第二种方法。还要注意,这不是性能问题。在选择一个对象而不是另一个对象时,您不太可能看到可测量的差异。@Kayaman每次都使用Long.valueOf创建任何新对象(如字符串中的对象)以进行强制转换或不转换?。你能解释第二种方法在哪方面是有益的吗