比较长的原因比比较双倍慢

Tor*_*örn 4 java double optimization runtime long-integer

我写了一个小程序来计算前18个三元(x,y,z)x<y<z,满足x^3+y^3=z^3+1.

我发现,在进行优化总运行时间的同时,使用double三次方程式和方程式的两侧比使用更快long.在我的机器上,差异大约是3秒.

现在我想知道为什么会这样.我猜它是在内部处理的某个地方,long而两个long变量的比较,因为这是唯一的,它在计算循环中发生变化.

这是我的代码:

class Threes {
  public static void main(String[] args) {
    System.out.println("Threes --- Java");
    int Z_MAX = 60000, Y_MAX = Z_MAX-1, X_MAX = Y_MAX-1;
    double[] powers = new double[Z_MAX+1];
    for (int i = 0; i <= Z_MAX; i++) {
      powers[i] = Math.pow(i, 3);
    }
    System.out.println("Powers calculated");
    int x, y, z;
    double right, left;
    int[][] sets = new int[18][3];
    int foundCount = 0;
    long loopCount = 0;
    long start, end;
    start = System.currentTimeMillis();

    for (x = 1 ; x < X_MAX; x++) {
      for (y = x + 1; y < Y_MAX; y++) {
        right = powers[x] + powers[y];
        for (z = y + 1; z < Z_MAX; z++) {
          left = powers[z] + 1;
          if (right < left) {
            z = Z_MAX;
          } else if (right == left) {
            sets[foundCount][0] = x;
            sets[foundCount][1] = y;
            sets[foundCount][2] = z;
            foundCount++;
            end = System.currentTimeMillis();
            System.out.println("found " + foundCount + ". set:\t" + x + "\t" + y + "\t" + z + "\t" + ((end - start) / 1000.0));
            if (foundCount == 18) {
              x = X_MAX;
              y = Y_MAX;
              z = Z_MAX;
            }
          }
          loopCount++;
        }
      }
    }
    System.out.println("finished: " + loopCount);
  }
}
Run Code Online (Sandbox Code Playgroud)

我更改的行是:

double[] powers = new double[Z_MAX+1];
Run Code Online (Sandbox Code Playgroud)

long[] powers = new long[Z_MAX+1];
Run Code Online (Sandbox Code Playgroud)

powers[i] = Math.pow(i, 3);
Run Code Online (Sandbox Code Playgroud)

powers[i] = (long)Math.pow(i, 3);
Run Code Online (Sandbox Code Playgroud)

double right, left;
Run Code Online (Sandbox Code Playgroud)

long right, left;
Run Code Online (Sandbox Code Playgroud)

"奖金问题":我有什么其他可能性来优化整个代码的总运行时间?我知道,遗漏loopCount给我几毫秒.我敢肯定,我必须显着减少循环迭代次数.但是怎么样?

Juh*_*uho 8

如果您使用的是32位操作系统,则长变量的性能可能会更差,因为long是64位类型.例如,对于64位操作系统,Java只能与一个机器指令进行比较,但在32位环境中,它必须使用多个机器指令,因为它当时只能处理32位.

但是对于double来说,这不是必要的,因为32位系统具有64位浮点数的机器指令,即使它们不具有64位整数的机器指令.

还有,代码:

powers[i] = (long)Math.pow(i, 3);
Run Code Online (Sandbox Code Playgroud)

有两个不必要的转换,首先i(整数)转换为double(这是Math.pow采用的),然后返回值转换回64位整数(long).