首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >构造函数中的JAVA - Array复制在大量调用后意外地慢下来

构造函数中的JAVA - Array复制在大量调用后意外地慢下来
EN

Stack Overflow用户
提问于 2018-04-05 14:36:45
回答 2查看 58关注 0票数 1

我目前正在努力提高Java代码的性能。在深入了解需要优化的地方之后,我得到了下面的设置(简化为清晰)。

委员会构造函数被称为大量的构造函数(~200 k到2M):

代码语言:javascript
复制
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);
    }
}

在另一个班级:

代码语言:javascript
复制
long end = System.currentTimeMillis() + SIMULATION_DURATION;
while (System.currentTimeMillis() < end) {
    ...
    ...
    Board board = new Board(otherBoard);
    ... 
    ...
}

结果使我困惑不解。事实上,我观察到了两件事:

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

我的问题如下:

  1. 怎么能花这么长时间复制一个9个整数数组呢?
  2. 为什么持续时间少于0.1ms,占时间的99%,而剩下的1%却真的很高?
  3. 为什么它依赖于SIMULATION_DURATION的值?
  4. 对于这种基准测试,使用System.currentTimeMillis()是否犯了错误,因此结果是完全不准确的?
  5. 当我创建大量的Board对象时,GC是否参与了这种奇怪的行为?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-05 14:47:02

听起来,您的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。

为什么持续时间小于0.1ms,占时间的99%,而剩下的1%却很高?

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

为什么它依赖于SIMULATION_DURATION的值?

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

我是不是对这类基准使用了System.currentTimeMillis()的错误,因此结果是完全不准确的?

检查指向上述其他堆栈溢出问题的链接。

是这个奇怪行为中的GC,因为我正在创建大量的Board对象?

检查上面的答案。

票数 4
EN

Stack Overflow用户

发布于 2018-04-05 15:04:35

普拉那瓦尔霍特拉的答案比我的更有价值,但有一个改进是肯定的,这是应该做的。

代码语言:javascript
复制
this.macroBoard = new int[9];
int[] boardToCopy = board.getMacroBoard();
for (int i = 0; i < 9; i++){
    this.macroBoard[i] = boardToCopy[i];
}

第一个优化是

代码语言:javascript
复制
this.macroBoard = new int[9];
int[] boardToCopy = board.getMacroBoard();
System.arraycopy(boardToCopy, 0, macroBoard, 0, 9);

甚至:

代码语言:javascript
复制
int[] boardToCopy = board.getMacroBoard();
this.macroBoard = Arrays.copyOf(boardToCopy, 9);

优化可以采取多种形式。如果板ints的范围为0 ..127,一个人可以把每7位int放入一个长,当7*9= 63 < 64位长。long是一种基本类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49675049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档