【问题标题】:Ternary Conditional causes weird CPU usage in Java三元条件导致Java中奇怪的CPU使用率
【发布时间】:2014-07-26 18:59:19
【问题描述】:

我正在运行这段代码来比较 3 种计算环绕坐标的等效方法的性能:

public class Test {
    private static final float MAX = 1000000;

    public static void main(String[] args) {
        long time = System.currentTimeMillis();
        for (float i = -MAX; i <= MAX; i++) {
            for (float j = 100; j < 10000; j++) {
                method1(i, j);
                //method2(i, j);
                //method3(i, j);
            }
        }
        System.out.println(System.currentTimeMillis() - time);
    }

    private static float method1(float value, float max) {
        value %= max + 1;
        return (value < 0) ? value + max : value;
    }

    private static float method2(float value, float max) {
        value %= max + 1;
        if (value < 0)
            value += max;
        return value;
    }

    private static float method3(float value, float max) {
        return ((value % max) + max) % max;
    }
}

我使用方法 1、方法 2 和方法 3(每次测试一个方法)运行此代码 3 次。

奇怪的是method1产生了几个java进程,并设法利用了我近100%的双核cpu,而method2和method3只产生了1个进程,因此只能占用我的cpu的25%(因为有4 个虚拟核心)。为什么会这样?

这是我的机器的详细信息:

Java 1.6.0_65

Macbook Air 13" 2013 年末

【问题讨论】:

  • 你没有在这里产生任何新线程。它也不会神奇地为您做到这一点。如果你看到多个 cpu 被使用,要么是你的 GC 疯了,要么你的 cpu 监控不正确。
  • 我怀疑是 GC。区别不在于三元运算符 - 它将在 +=+ 之间,因为前者不需要空间来存储新值,而后者则需要。
  • 我认为您的意思是线程,而不是进程。我支持 GC 假设,但我想知道您是如何注意到产生的线程的。不是那么相关,但我在我的盒子上运行它并且对所有这些都或多或少地获得相同的时间,第三个有点慢。另外,请记住,拥有多个线程并不一定会导致使用多个内核。
  • 根据到目前为止的描述,我的猜测既不是 GC 也不是任何其他与程序相关的开销。听起来您只是(意外地)启动了您的程序几次,通过单击“运行”按钮,而前一次运行尚未完成(因为,正如您所说,这将需要“20 分钟才能完成”)......投票结束这个。
  • 请阅读微基准。您的代码没有任何副作用,因此热点编译器可能随时启动并决定没有什么可以计算 amyway。我对许多线程的牵强猜测将是编译器线程。为确保编译器不会优化所有内容,只需汇总方法的输出并最后打印即可。

标签: java cpu-usage ternary-operator


【解决方案1】:

在审查了各种 cmets 并未能始终如一地复制行为之后。我已经确定这确实是 JRE 的侥幸。感谢 cmets,我了解到这种方式的基准测试不是很有用,我应该使用微基准测试框架(例如 Google 的 caliper)来测试这些微小的差异。

我找到的一些资源:

  1. Google's java micro-benchmark page
  2. IBM page discussing a flawed benchmark and common pitfalls
  3. Oracle's page on micro-benchmarking
  4. Stackoverflow question on micro-benchmarking

【讨论】:

  • 只是一个站点注释:无论如何它可能不相关。即使你有一个相关的场景,那么上下文也很重要:JIT 之前和之后发生的事情可以内联或优化它。如果您使用良好的基准测试框架 (JMH),综合测试单个条件的性能可能会更好,但在您的实际代码中可能不一样(并且与其性能无关)。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 2017-10-03
  • 2018-09-04
  • 1970-01-01
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多