热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我有一个返回0或1的Java方法.我可以让它返回一个布尔值而不生成分支指令吗?

如何解决《我有一个返回0或1的Java方法.我可以让它返回一个布尔值而不生成分支指令吗?》经验,请帮忙看看怎么搞?

在字节代码级别,Java布尔值表示为0或1.我有一个表达式,结果为0或1,但它是使用int类型计算的.一个简单的例子是:

public static int isOdd_A(int value) {
    return value & 1;
}

public static boolean isOdd_B(int value) {
    return (value & 1) == 1;
}

上述方法的字节代码如下所示:

  public static int isOdd_A(int);
    descriptor: (I)I
    Code:
       0: iload_0
       1: iconst_1
       2: iand
       3: ireturn

  public static boolean isOdd_B(int);
    descriptor: (I)Z
    Code:
       0: iload_0
       1: iconst_1
       2: iand
       3: iconst_1
       4: if_icmpne     11
       7: iconst_1
       8: goto          12
      11: iconst_0
      12: ireturn

返回布尔值的方法要大得多,并且包含一个分支,因此如果运行的机器代码是等效的,则它不是最佳的.

HotSpot JVM是否知道布尔版本可以优化为无网格机器代码?有没有办法欺骗Java使用基于int的字节代码来返回一个布尔值的方法(例如使用ASM)?

编辑:许多人认为这不值得担心,总的来说我同意.但是我确实创建了这个微基准测试并用jmh运行它,并注意到int版本大约10%的改进:

@Benchmark
public int countOddA() {
    int odds = 0;
    for (int n : numbers)
        if (Test.isOdd_A(n) == 1)
            odds++;
    return odds;
}
@Benchmark
public int countOddB() {
    int odds = 0;
    for (int n : numbers)
        if(Test.isOdd_B(n))
            odds++;
    return odds;
}

Benchmark                Mode  Cnt      Score    Error  Units
OddBenchmark.countOddA  thrpt  100  18393.818 ± 83.992  ops/s
OddBenchmark.countOddB  thrpt  100  16689.038 ± 90.182  ops/s

我同意代码应该是可读的(这就是为什么我想要具有适当布尔接口的无分支int版本的性能),并且大多数时候这种优化级别是不合理的.然而,在这种情况下,即使所讨论的方法甚至不占大多数代码,也有10%的增益.

所以我们在这里可能会有一个案例,可以让HotSpot了解这种模式并生成更好的代码.


推荐阅读
author-avatar
Stupid锋_891
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有