JAVA - 大量调用后构造函数中的数组复制意外变慢

标签 java arrays monte-carlo-tree-search

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

被调用次数较多(~200k 到 2M)的 Board 构造函数:

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 = 10 秒时,max(duration) 的值可以达到 2 秒(是秒,没有错字)。如果 SIMULATION_DURATION = 100 毫秒,我观察到大约 30 毫秒的max(duration)

我的问题如下:

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

最佳答案

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

此外,我建议使用 System.nanoTime() 来衡量性能。更多详情:System.currentTimeMillis vs System.nanoTime

直接回答问题:

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

当然不应该。检查 GC 日志以确认 GC 正在减慢 VM。

为什么 99% 的时间持续时间小于 0.1 毫秒而其余 1% 的时间非常高?

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

为什么取决于 SIMULATION_DURATION 的值?

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

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

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

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

检查上面的答案。

关于JAVA - 大量调用后构造函数中的数组复制意外变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49675049/

相关文章:

python - 如何让我的 AI 算法玩 9 板井字游戏?

java - 在 WordNet 中搜索 Synonym 只给出一个结果

java - 找到绕过多个市场的最短和最便宜的路径

python - 将 numpy 数组从一个(2-D)复制到另一个(3-D)

javascript - 如何将 uri 响应传递给另一个函数并获取长度?

artificial-intelligence - MonteCarloTreeSearch 是适合这个问题规模(大 Action /状态空间)的方法吗?

java - ANTLR 4 - 树模式匹配

java - OpenCV 选择灰色颜色范围

java - System.arraycopy 获取 java.lang.ArrayIndexOutOfBoundsException

artificial-intelligence - 蒙特卡洛树搜索 - 处理游戏结束节点