简体   繁体   中英

How do I efficiently iterate through a big list?

I want to make a open world 2D Minecraft like game and have the world load in Chunks (just like MC) with a size of 16x16 blocks (a total of 256 blocks). But I found out through iterating 256 times that it takes almost 20ms to iterate completely with a code like this:

long time = System.nanoTime();
for(int i = 0; i < 16*16; i++)
{
    System.out.println(i);
}
System.out.println(System.nanoTime() - time);

And since I'm not only going to print numbers but also get a block, get it's texture and draw that texture onto the frame, I fear it might take even longer to iterate. Maybe I just exaggerate a bit, but is there a way to iterate faster?

It's not the iteration that takes 20ms, it's println(); . The following will be much faster:

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);

So, first off, take into account that a list with 256 is not considered generally to have a big size.

The main thing consuming time your code is not iterating through the list but using System.out.println() . Printing to console (or any I/O action) tends to take longer than other instructions.

When I try your code locally I get roughly 6 ms but if I do something like this:

    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);

I get 0.5ms.

If that approach is not suitable for your needs then you would need to do as other comments say, consider traversing different parts of the list in parallel, maybe move to a different kind of traversal or even a different kind of structure.

Hope this helps.

You should ask yourself if you really need to do all that work. Do you need to draw things that are not seen by the camera for example? Of course not, so exclude every block in that chunk that is outside the camera rect.

Filtering out the blocks not seen implies some overhead but it is generally worth it compared to drawing every block in the chunk on each render update because drawing stuff is quite a heavy operation.

If you only want to speed up the traversal you could spawn threads that traverse the chunk in parallell or buy better hardware. But it is better to start with the question of how you could achieve the same result with less work put in.

On the other hand your computer should probably be able to draw 256 textures without problem especially if done on the gpu. So maybe do some testing before making premature optimizations.

PS. It isn't really the traversal itself you want to optimize for but rather the work done in each iteration. Just iterating 256 times is going to be quite fast.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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