简体   繁体   中英

Should i use lookup-lists instead of a lot of multiplication?

in my application I have a very large array of bytes, its a flattened 3 dimensional array, we populate the array using 3 nested for loops (x, y, z) and then we get the values we want by using a little bit of math, most specifically:

To get an index in the array:

return x + z*SizeX + y*SizeX*SizeZ;

and to return the x/y/z coordinates, given an index:

int index = pos;
var y = (ushort) (pos/SizeX/SizeZ);
pos -= y*SizeX*SizeZ;
var z = (ushort) (pos/SizeX);
pos -= z*SizeX;
var x = (ushort) pos;

return new BlockPos(x, y, z, index, this);

First off, I would imagine the second one can be made more efficient, i just don't know how to do it, any help there would be appreciated :P

My main quesion is, would it be faster for me to make a lookup table for the y and x values (populating when the class is loaded) or is it faster to just leave the multiplication in there?

edit This math is called a LOT in some cases, so if it would be faster, even for a longer startup it would make a differance better.

In most languages and architectures, multiplication will become one (or a few) machine instructions. Whilst those instructions may be relatively expensive, they should still be cheaper that performing a lookup operation - and a lookup operation may very well require a multiplication anyway.

Eg "locate the 4th element of the array" will be

<array base address> + (3 * <array element size>)

The only optimization I'd recommend given your pseudo code is to perform the "constant" operations (eg SizeX*SizeZ ) once, and store those results.

These might speed you up;

  • Make SizeX, SizeY, SizeZ constants
  • Precompute SizeXZ = SizeX * SizeZ and the others (also as constants);

pre-computing array indices will not gain you much as the precomputed list will be pretty large and looking into it will probably not be faster as doing very little easy math.

Array operations in C# are relatively slow (compared to some other languages) because most access is bounds checked. There are some ways to get around that;

  • put a tight arrayloop in an unsafe section and use pointers see Large array arithmetics in C# or google for 'matrix multiplication unsafe c#'
  • Mono has a parameter to skip bounds checking. It might be faster in your case

Another speedup can be had to arrange your math loops in such a way that your math processing accesses the large array sequentially. In that way each access benefits from the fact that the data is usually already fetched into the cpu-cache by the previous computation. So structure the x,y,z loops in such a way that you get index=1, index=2, index=3 etc. And NOT index = 0, index= 256, index = 512 etc..

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