繁体   English   中英

如何有效地遍历大列表?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM