我目前正在努力提高Java代码的性能。在深入了解需要优化的地方之后,我得到了下面的设置(简化为清晰)。
委员会构造函数被称为大量的构造函数(~200 k到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);
...
...
}结果使我困惑不解。事实上,我观察到了两件事:
我的问题如下:
发布于 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对象?
检查上面的答案。
发布于 2018-04-05 15:04:35
普拉那瓦尔霍特拉的答案比我的更有价值,但有一个改进是肯定的,这是应该做的。
为
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);优化可以采取多种形式。如果板ints的范围为0 ..127,一个人可以把每7位int放入一个长,当7*9= 63 < 64位长。long是一种基本类型。
https://stackoverflow.com/questions/49675049
复制相似问题