1

我目前正在尝试提高 Java 代码的性能。在深入了解需要优化的地方后,我最终得到了以下设置(为清楚起见进行了简化)。

被大量调用的 Board 构造函数(~200k 到 2M):

public Board(Board board) {
    long now = System.currentTimeMillis();

    this.macroBoard = new int[9];
    int [] boardToCopy = board.getMacroBoard();
    for (int i = 0; i < 9; i++){
        this.macroBoard[i] = boardToCopy[i];
    }

    long duration = System.currentTimeMillis() - now;
    if (duration > THRESHOLD){
        System.err.println(duration);
    }
}

在另一个班级:

long end = System.currentTimeMillis() + SIMULATION_DURATION;
while (System.currentTimeMillis() < end) {
    ...
    ...
    Board board = new Board(otherBoard);
    ... 
    ...
}

结果让我很困惑。事实上,我观察到两件事:

  1. SIMULATION_DURATION 越大,max(duration)越大;
  2. 当 SIMULATION_DURATION = 10s 时, max(duration)的值可以达到 2s(是秒,没有错字)。如果 SIMULATION_DURATION = 100 毫秒,我观察到最大(持续时间)约为 30 毫秒。

我的问题如下:

  1. 9 个整数数组的副本怎么会花这么长时间?
  2. 为什么持续时间在 99% 的情况下小于 0.1 毫秒,而剩下的 1% 则非常高?
  3. 为什么它取决于 SIMULATION_DURATION 的值?
  4. 我是否在使用 System.currentTimeMillis() 进行这种基准测试时犯了错误,因此结果完全不准确?
  5. 当我创建大量 Board 对象时,GC 是否参与了这种奇怪的行为?
4

2 回答 2

4

听起来您的 VM 内存不足并正在尝试 GC,以便它可以为新数组分配内存。您可以在此链接中找到信息以启用 GC 日志记录并获取有关我们 VM 的 GCing 行为的更多详细信息:https ://dzone.com/articles/enabling-and-analysing-the-garbage-collection-log

另外,我建议使用System.nanoTime()来衡量性能。有关更多详细信息:System.currentTimeMillis 与 System.nanoTime

直接回答问题:

9 个整数数组的副本怎么会花这么长时间?

它绝对不应该。检查 GC 日志以确认 GC 正在减慢 VM。

为什么持续时间在 99% 的情况下小于 0.1 毫秒,而剩下的 1% 则非常高?

在 99% 的时间里,您没有用完内存,因此为新Board对象分配空间没有问题。

为什么它取决于 SIMULATION_DURATION 的值?

的值SIMULATION_DURATION直接控制Board对象的数量。

我是否在使用 System.currentTimeMillis() 进行这种基准测试时犯了错误,因此结果完全不准确?

检查上面其他堆栈溢出问题的链接。

当我创建大量 Board 对象时,GC 是否参与了这种奇怪的行为?

检查上面的答案。

于 2018-04-05T14:47:02.047 回答
1

pranavmalhotra 的答案比我的更有价值,但是肯定应该做一些改进。

为了

this.macroBoard = new int[9];
int[] boardToCopy = board.getMacroBoard();
for (int i = 0; i < 9; i++){
    this.macroBoard[i] = boardToCopy[i];
}

第一个优化是

this.macroBoard = new int[9];
int[] boardToCopy = board.getMacroBoard();
System.arraycopy(boardToCopy, 0, macroBoard, 0, 9);

甚至:

int[] boardToCopy = board.getMacroBoard();
this.macroBoard = Arrays.copyOf(boardToCopy, 9);

优化可以采取多种形式。如果板整数的范围为 0 .. 127,则可以将每 7 位整数放入一个长整数中,因为 7 * 9 = 63 < 64 位长整数。Along是原始类型。

于 2018-04-05T15:04:35.507 回答