I don't believe in early optimization, nor in macros, but if you really want to go for it...
If you intend on using 8 bits (char) then you can use a macro/function to calculate the offset in a faster way by manipulating bits.
Code:
#define DIV_8( x ) ( (x) >> 3 )
#define MOD_8( x ) ( (x) & 0x07 )
Then you can avoid shifting to get the bit mask by precomputing the eight bit masks you will need:
Code:
char masks[] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
So that the mask you want to apply is `mask[ MOD_8( POS(x, y) ) ]` in your code, for just one indirection.
Code:
// SET is easiest, can precompute the position and keep it, as it does not return it can be a
// block of code, it is also the safest as arguments are only used once
#define SET( data, x, y ) { register int pos=POS((x),(y)); (data)[ DIV_8(pos) ] |= mask[ MOD_8(pos) ]; }
#define GET( data, x, y) ((data)[ DIV_8( POS((x),(y)) ) ] & mask[ MOD_8( POS((x),(y)) ) ]
Of course, the compiler can do anything it wants to with the register keyword, but in most cases (even if you did not actually requested it) it will be able to keep it in a register (the scope is minimal, just three instructions all of which do use the variable).
Now, I recommend that you do not go this way and instead use regular functions. At any rate, and seeing the use of macros in your OP, note that you should use parenthesis around all the arguments to avoid problems with the code after the macro expansion. Also note that if an argument is used more than once inside the macro (as in GET) you risk users having unexpected results when they call the macro: GET( i++, j++ ) will increment both i and j variables twice (as compared to the SET( i++, j++ ) that will only increment each variable once.
A last remark, how big is a HUGE array of bools? Note that you are sacrificing performance for memory, and current systems do have lots of memory (and CPU for that matter), but anyway, given current hardware, in most cases you would be better helping programmers (that is regular functions, regular data structures) than helping the computer. Just think of how much your time costs as compared to CPU/memory costs... how much work will you do to avoid buying a 4 Gb ram module for less than 75€, how much work do you want to spend to save for a 10% performance that can be payed by 50€ worth of CPU upgrade (from one frequency to the next would probably be less than that, just rough numbers).
Bookmarks