I always keep tiles in 1D array and draw them either with 2 for loops (accessing tileID with tiles[x+y*mapWidth]) or something like this:
(rough example)
int mapWidth = 2;
int mapHeight = 2;
int[] tiles = {
1, 1
1, 2
};
for(int i = 0; i < tiles.length; i++) {
int x = i % mapWidth;
int y = i / mapWidth;
int tileID = tiles[i];
draw(tileID, x, y);
}
final int mask = 15, shift = 4; // 16 x 16
for(int i = 0; i < tiles.length; i++) {
int x = i & mask;
int y = i >> shift;
int tileID = tiles[i];
draw(tileID, x, y);
}
for powers sizes of two. Or for everything else:
for(int i = 0, x = 0, y = 0; i < tiles.length; i++)
{
if(++x == width)
{
x = 0;
y++;
}
int tileID = tiles[i];
draw(tileID, x, y);
}
I don’t think you are looking at my or PaidGEEK’s code correctly.
What good would storing the tile’s location do? You want to know if the tile at (10, 15) is grass or water, not where a tile that happens to grass is located.
In a 1 or 2D array, you can find a tile’s location given its index or a tile’s index given its location.
Where do you get world and screen coordinates from? I see an assignment to x and y, but their values are derived from an array index not a separate X, Y pair.
Also, any assignment using ints in the form “a = b (operator) c;” is going to be much faster than an array look up.
Nah, they’re just using funky ways to get around using nested loops to iterate through the tile list, and still have a coordinates on hand by calculating them from the index and ‘width’. Some say it’s faster than a nested for loop. I don’t have any evidence as to which is faster though.
If know you have a wide 2D array, you can save some mults by premultiplying the width:
for(int y=0;y<h;y++) {
int wy = y*w;
for(int x=0;x<w;x++) {
int i = wy+x;
//stuff
}
}
Oh, now I feel like an idiot. Deleted my post! I didn’t realize what you were trying to accomplish, I just glanced at your code and thought that you were doing something funky. Sorry!
I agree with @opiop65 - nested loops are frequently used for multi-dimensional arrays, it makes most sense to me to use one.
Neither one is faster than the other - well, not to a point where it really matters anyway. Just chose the one that is easier to read for you (personally I find a nested loop easier to read)
Actually, now I’m wondering if it is faster. Has anyone tested that theory out? If so, its not too big of a change if it helps out with performance. Its really odd to read, but that’s ok if I can scrape a few extra frames out using it. Although I agree, I would rather use nested loops.
It won’t be faster. If it is, it doesn’t even matter.Almost anything you can do in those loops will literally dwarf the time spend multiplying two numbers. It would be a relatively extreme micro-optimization.
I agree, these kind of things are mostly a waste of time, and belong in the performance tuning board
The only time I have had any real use for playing with loops and micro-optimizing them was a long time ago in a program where I had to loop through half a million items every frame, and maintain several hundred fps. Other than such edge cases, it’s a non-issue.
Actually, don’t use the second example I had. You can use nested loops with a one dimensional array and avoid the if while still avoiding division and mod. :-X Not that it matters a lot, but if you wanted to bother using a 1D array then you may as well make x y calculations fast, too.
I could be appropriate in some cases. Something is not a micro-optimization just because one line of code is different.
If you have a big array you want to be conscious of what order you traverse it in. If swap you the order of your x and y for loop, you would be accessing every w’th element instead of doing sequential access, which could have poor RAM performance. You also create a new object for each row with a 2D array. The difference between division/modulo and shift/mask or division/modulo and incrementing is big, but not nearly as much as the first thing.
Of course, that only matters if you are performance conscious of what is in the loop body. If you are dereferencing object variables or drawing in the loop, you won’t see a difference. And you only need to be performance conscious if its something that does a lot of work, such as collision detection used by AI.
I don’t think it is micro-optimization because it is one line of code. It is micro-optimization because we are comparing multiplication performance overhead in what is likely adjacent to much more comprehensive render or update routine that no one has started talking about.
Ofcourse you can alter the context of anything to counter an argument, but I am speaking to the application here.
@BurntPizza I agree with the sentiment, but sometimes you write a major portion of your game engine, find out it does not scale as well as it did with your test levels did once other features are added in, and then have to do a complete overhaul of your engine from scratch. :emo: It is good advice, but like all rules you eventually learn some exceptions. I would not give new programmers the opposite advice, but I also would never tell them not to optimize disregard design decisions of a section of code they know will be hot. (Though the reason the rule exists is because people are notoriously bad at estimating what parts will eventually be a bottle neck.)
This quote from Wikipedia [quote]A better approach is therefore to design first, code from the design and then profile/benchmark the resulting code to see which parts should be optimized. A simple and elegant design is often easier to optimize at this stage, and profiling may reveal unexpected performance problems that would not have been addressed by premature optimization.
[/quote]
would not be complete without this one:
[quote]In practice, it is often necessary to keep performance goals in mind when first designing software, but the programmer balances the goals of design and optimization.
[/quote] @Jeremey I agree. My answer was limited to the context of opiop65’s question. Yours is the same caveat I gave opiop65.