[英]How do I efficiently iterate through a big list?
我想制作一个像 Minecraft 这样的开放世界 2D 游戏,并在 Chunks 中加载世界(就像 MC 一样),大小为 16x16 块(总共 256 个块)。 但是我通过迭代 256 次发现,使用这样的代码完全迭代需要将近 20 毫秒:
long time = System.nanoTime();
for(int i = 0; i < 16*16; i++)
{
System.out.println(i);
}
System.out.println(System.nanoTime() - time);
由于我不仅要打印数字,还要获取一个块,获取它的纹理并将该纹理绘制到框架上,我担心迭代可能需要更长的时间。 也许我只是夸大了一点,但有没有办法更快地迭代?
不是需要 20ms 的迭代,而是println();
. 以下将更快:
long time = System.nanoTime();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 16*16; i++)
{
sb.append(i + System.getProperty("line.separator"));
}
System.out.println(sb);
System.out.println(System.nanoTime() - time);
因此,首先,请考虑到通常不认为具有 256 的列表具有大尺寸。
消耗代码时间的主要事情不是遍历列表而是使用System.out.println()
。 打印到控制台(或任何 I/O 操作)往往比其他指令花费更长的时间。
当我在本地尝试你的代码时,我得到大约 6 毫秒,但如果我做这样的事情:
long secondStart = System.nanoTime();
StringBuffer stringBuffer = new StringBuffer();
for(int i = 0; i < 16*16; i++)
{
stringBuffer.append(i);
stringBuffer.append("\n");
}
System.out.println(stringBuffer);
System.out.println(System.nanoTime() - secondStart);
我得到 0.5 毫秒。
如果这种方法不适合您的需求,那么您需要像其他评论所说的那样做,考虑并行遍历列表的不同部分,可能转向不同类型的遍历甚至不同类型的结构。
希望这可以帮助。
您应该问问自己是否真的需要完成所有这些工作。 例如,您是否需要绘制相机看不到的东西? 当然不是,因此排除该块中位于相机矩形之外的每个块。
过滤掉看不见的块意味着一些开销,但与在每次渲染更新时绘制块中的每个块相比,它通常是值得的,因为绘制内容是一项非常繁重的操作。
如果您只想加快遍历速度,您可以生成并行遍历块的线程或购买更好的硬件。 但是最好从如何以更少的工作量获得相同结果的问题开始。
另一方面,您的计算机应该能够毫无问题地绘制 256 个纹理,尤其是在 GPU 上完成时。 所以也许在进行过早优化之前做一些测试。
附注。 您真正想要优化的并不是遍历本身,而是每次迭代中完成的工作。 只需迭代 256 次就会非常快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.