On Sun, 26 Nov 1995, Pink Floyd wrote: > Does anyone know if bitfields are much less efficient than bitvectors? > For various reasons, I was considering the idea of switching all the > bitvectors over to bitfields, something like this: > currently, chars have an int affected_by, where each affect is predefined > to be a certain bit.. (e.g., AFF_SANCTUARY is (1 << 2) which is the third > bit).. you can have up to 32 bits if your system is 32 bit ints. (btw, > don't take these literally, I don't remember what the actual value of > AFF_SANC is, this is just example). To see if a player is affected by a > certain affect, you do a bitwise AND: > if (ch->affected_by & AFF_SANCTUARY) > ... > This allows for easy checks of multiple affects: > if (ch->affected_by & (AFF_1 | AFF_2 | AFF_3)) > /* will return true if affected_by has any of those bits set */ > > The way this would be done with bitfields would be to change the > int affected_by to a bitfield: > > #typedef unsigned int us; > struct affected_by_bitfield { > us aff_sanctuary : 1; /* this field is to take up 1 bit */ > us aff_hide : 1; > us aff_invis : 1; > ... > }; > /* in char_data */ > ... > struct affected_by_bitfield affected_by; > ... > > Then, to test an affect you would do this: > if (ch->affected_by.aff_invis) > ... > To check multiple entries, you would use > if (ch->affected_by.aff_invis || ch->affected_by.aff_hide) > ... > > I realize this would require a complete rewrite of many macros, but there > are some benefits to this. One is that you can add an arbitrary number of > new affects, and if you break 32 you don't have to worry about dealing with > int affected_by1; > int affected_by2; > ... > Also, you can put in many blanks for future expansion by doing this: > ... > aff_hide : 1 > extras : 100 > } > then to add a new one, simply: > ... > aff_hide : 1 > aff_new : 1 > extras : 99 /* pfile is not corrupted */ > } > The size of the bitfield in bytes will be the number of bits allocated, > divided by 8, rounded up. > None of this would be visible to the user, but it could make your code more > structured. Well, ANSI C doesn't guarantee, that bitfields which extend the size of an int, are allowed afaik. I guess most compilers will support such a feature, but you can't be sure, i never tried it myself. Though extras: 99 won't be supported by many compilers i guess. > My question for you more experienced C programmers is, how do you think that > this would affect efficiency? I get the feeling that it could actually > improve efficiency, as well as produce smaller code. > For the bitvectors, the operations required to check are this: > if (ch->affected_by & aff_bit) > 1. dereference ch pointer > 2. bitwise AND it with a constant (fast, but also required storage of that > constant in memory) > 3. test if the result is true > > for bitfield: > if (ch->affected_by.aff_bit) > 1. dereference ch pointer > 2. calculate offset of aff_bit (probably the bottleneck) > 3. test is result is true > > Is this a correct analysis? What are other reasons (not) to switch to > bitfields? I wouldn't expect any better efficiency with bitvectors, since most probably Compilers use internally & and | when accessing bit fields anyway. :-) Though it would be more readable maybe. Herbert [on public request 12 lines of signature deleted] *snip* ;)
This archive was generated by hypermail 2b30 : 12/07/00 PST