Using bit fields in ActionScript 3

Update: I just confirmed with the player team that a Boolean actually takes up 4 bytes.

I’ve been doing a lot of research lately on different uses for ByteArrays. This is in preparation for my ByteArrays for Beginners session that I will be doing at FITC Toronto. While in Amsterdam recently, Thibault Imbert of bytearray.org mentioned how he uses bit fields in WiiFlash to make boolean values as small as possible. Basically when the WiiFlash server sends over the state of the Wiimote buttons to Flash, it sends over a single byte where each bit represents the state of a particular button.

So why would you want to do this? Well if you have eight boolean values it would take up 32 bytes of space if you use the native Boolean class, as each one takes up 4 bytes. But in reality that is 32 times as big as it needs to be. If you set each bit of a single byte to either 1 or 0 based on your boolean values it will only take up a single byte. Now this is not going to be worth it for most situations, but if you need really high-speed binary communication than it will be more efficient. Below is an example of how you could pack eight booleans into a single byte:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var ba:ByteArray = new ByteArray();
var bf:uint = 0;

bf = 1<<7;  //Set bit 8 to true
bf |= 1<<6; //Set bit 7 to true
bf |= 0<<5; //Set bit 6 to false
bf |= 1<<4; //Set bit 5 to true
bf |= 1<<3; //Set bit 4 to true
bf |= 1<<2; //Set bit 3 to true
bf |= 1<<1; //Set bit 2 to true
bf |= 1;    //Set bit 1 to true

ba.writeByte(bf);
trace(ba[0].toString(2)); //11011111

In the above code all of the boolean values are set to true except for bit number 6. This way of setting individual bits is probably the easiest to read, at least for me. Now when you want to retrieve the value of an individual bit you can simply do an AND on the byte like I do below.

1
if(ba[0]&32) trace("Bit 6 is true"); //Won't trace anything

The reason I chose the number 32 is that it is the perfect binary mask to retrieve the 6th bit of the byte. In binary the number 32 is represented as 00100000. I will go over this more during my session and will also do a tutorial on it soon.

Lee

Comments

  1. March 24th, 2009 | 5:41 pm

    Deep….

    I could see this being used in a situation where you were passing data to another app or over the web with a lot of yes/no settings. I suppose the WiiFlash example is proof enough. Thanks Lee.

  2. March 24th, 2009 | 5:41 pm

    I first used a Byte key (technically a 32 bit Integer key) in Flash 5 for a calendar application for PricewaterhouseCoopers. What’s great about Byte keys is an entire year of ‘on/off’ data can be stored in only 12 Integers (One Integer per month; no month greater than 31 days, so you’re golden). We were able to shoot out a year of calendar data tracking 4 different categories per day with only 48 Integers then (4×12x32bits). It sped up the results so fast, we actually needed to add a ‘delay timer’ since none of the users in 1999 were expecting the data to be saved that quickly. Byte keys are a GREAT way to get out of a pickle, a righteous hack that’s good to know and I’m stoked you’ll be sharing it with the broader Flash community. Nice work.

  3. March 24th, 2009 | 5:43 pm

    Nice, Finally understand what you were talking bout yesterday. Can this only be used to send Booleans or can I send other things such as Sprites or Array even??

  4. March 24th, 2009 | 5:50 pm

    Its also easy to toggle the individual bits:
    var bits :int = 0;
    bits |= 4; // (1 << 2)
    bits |= 32; // (1 << 5)
    trace(bits.toString(2)); // 00100100
    bits ^= 4; // mask off bit 3
    trace(bits.toString(2)); // 00100000
    bits ^= 32; // mask off bit 6
    trace(bits.toString(2)); // 00000000

    Also see http://www.vipan.com/htdocs/bitwisehelp.html

  5. TK
    March 24th, 2009 | 6:02 pm

    I could see how this would be useful in a project where extreme speed is of the essence… like in a socket protocol or something, but for everyday stuff, I don’t know if I would ever actually use this. Maybe the next AVM should condense Boolean values to bits so we don’t even have to do this?

  6. ian
    March 24th, 2009 | 7:24 pm

    Very nice! Cool thinking that one byte could hold say 8 pieces of personal information such as:
    Married / Single
    Straight / Gay
    Unemployed /Employed
    Renting / Buying
    Veteran / Not Veteran
    Lease / Own
    Pet / No Pet
    Apple / PC
    Or am I way off track with this?
    Looking forward to the future videos.

  7. March 24th, 2009 | 8:49 pm

    Nice. Looking forward to the video Lee ;)
    Thought I might see your name popup on the WebDU speakers list but no such luck :(

  8. March 24th, 2009 | 9:46 pm

    I find byte arrays and bit manipulation in general a very good way to save data out to a database in some cases. I am working on a scheduling app right now and each time-slot has a day of the week, start time, and end time and I can fit it all in a single UINT. Obviously this isn’t good for readability but it’s way more efficient in terms of space, and can speed up load times if the users needs a lot of info.

  9. March 25th, 2009 | 1:17 am

    While it is true that a Boolean value in low-level languages (which may or may not represent it as a boolean-specific data type) would take up one byte (lowest amount of addressable space), am I wrong in remembering having seen somewhere that all variables in Flash take up more memory?

    EDIT: Found the link saying 12 bytes, might just be relevant to AVM1. Can you spread some light? :)
    http://www.adobe.com/go/tn_14437

    It would make sense, since not only does the AVM need to hold the actual value, but the name of or other reference id for the variable, any metadata, et c.

  10. Shoom
    March 25th, 2009 | 2:11 am

    I use this technique quite often in php/mysql when I need to store various selections for e.g. a profile in a database and don’t want to have lot’s of fields in my table. The speed aspect of it never came to mind.
    Thanks!

  11. March 25th, 2009 | 2:25 am

    Next stop: POKE and PEEK!

  12. March 25th, 2009 | 4:35 am

    This kind of thing is used a lot in setting things like sort parameters or dialog button choices. For instance, sorting Arrays in AS. trace out:

    trace(Array.CASEINSENSITIVE);
    trace(Array.DESCENDING);
    trace(Array.UNIQUESORT);
    trace(Array.RETURNINDEXEDARRAY);
    trace(Array.NUMERIC);

    you get

    1 or 00001
    2 or 00010
    4 or 00100
    8 or 01000
    16 or 10000

    This way you can combine multiple options with the bitwise OR operator: |

    array.sort(Array.CASEINSENSITIVE | Array.DESCENDING);

    This passes 00011, or 3.

  13. March 25th, 2009 | 6:08 am

    I use this sort of thing for page tracking of my e-learning courses. We are limited in using 255 character strings for this. Sometimes a client asks to go beyond the specs and using bit data alleviated some of my concerns.

    Looking forward to the video Lee. I will see you in TO for the workshop, albeit I cannot attend your session because I have to get home.

    DJ

  14. CaptainCode
    March 25th, 2009 | 11:35 am

    @Richard Olsson

    in the AVM2, according to the tuning guide published by Adobe on their website, a integer without annotations takes 4 bytes, a uint is the exact same. Booleans, however, qualify as Atoms still in AS3. Which would make their size 4 bytes from what I have read. Lee, if I have something incorrect, feel free to correct me.

  15. Damion Murray
    March 25th, 2009 | 5:34 pm

    Cool stuff. I’m a big fan of bit-twiddling though there is little use for that kind of knowledge now-a-days. In any case check out the following link I occassionally use as a resource for bit-hacks:

    http://www-graphics.stanford.edu/~seander/bithacks.html

  16. March 26th, 2009 | 4:02 am

    Indeed, this way of handling Booleans is a little cumbersome for everyday use, especially for beginners. But for speed or memory space it’s just excellent.

    This means we should pay more attention to bitwise operations since they’re way faster. Also, it could be used when working with Boolean flags and save their states in a single integer value, as it was previously pointed out.

    Thank you Lee.

  17. March 26th, 2009 | 4:04 am

    [...] The Flash Blog that a Boolean takes up 4 bytes (confirmed by the Flash player team). Initially, in his article he wrote about one byte being occupied by a Boolean but he updated it later [...]

  18. March 26th, 2009 | 12:06 pm

    this is all because the “native” boolean classes as you called them are really what I call a “womenized booleans”. that’s the reason why it takes 4 bytes. the values that can be assigned are as follows: true / false / maybe / next week

  19. March 29th, 2009 | 12:30 pm

    [...] > The Flash Blog » Using bit fields in ActionScript 3 [...]

  20. March 31st, 2009 | 1:39 pm

    Thanks for the technical overview! I don’t often need to be this stringent on code, but when I do I’ll now be prepared!

  21. March 31st, 2009 | 9:55 pm

    great article. great comments.
    it’s great when i learn something so empowering. i look forward to more..

    thanks lee
    thanks community

  22. March 31st, 2009 | 10:56 pm

    [...] I was just reading one of my favorite blogs, rightfully named theFlashBlog.com, where Lee posted a great article on ByteArrays. He’s having a session FITC Toronto called ByteArrays for Beginners. I wish I [...]

  23. April 7th, 2009 | 8:43 pm

    This changes the way I fell about ByteArray. Great post thanks Lee.

  24. May 14th, 2009 | 5:27 am

    bit 6 is false because it’s never set. i think you meant:
    bf &= 0 << 5

  25. June 29th, 2009 | 5:52 pm

    [...] Lee Brimelow – ByteArrays for Beginners [...]

  26. Steve
    August 24th, 2009 | 11:32 am

    Great article.
    I’m still searching for your conference notes and/or tutorial on ByteArrays. Have these been posted somewhere?

  27. October 18th, 2009 | 7:05 am

    You’ve helped me finally understand what ByteArrays are all about. Thank you very much!

Leave a reply