AS3 Interesting Numeric Storage Behavior

When storing numbers in AS3 VM Andre Michelle and his collegue Bram de Jong at splicemusic found an interesting behavior of the internal uint storage.  When the numbers are stored they change from int to Number depending on range.  Why does this matter?  Because ints are faster than Numbers and during larger simulations with lots of math it could slow things down quite a bit at these types change. 

The disadvantage of this is that Numbers are slower in computation as well as reading, writing in an Array.

The internal findings when storing a uint 

From 0 to 27 it is int
From 28 to 31 it is Number
From 32 to 59 it is int (again)
From 60 to 63 it is Number (again) …

Found when reading another excellent polygonal labs post on benchmarks and performance (this one is great as well concerning faster operations using bitwise shifts or alternate ways to eek out more performance) where he wisely advises to use signed int for loops or iterations rather than uint where needed because the iterations with numbers will be slower.

Andre Michelle posted an Adobe response on the issue and it is a known and by design characteristic due to the metadata that is stored with the datatype in the AS3 virtual machine.          

The AS3 VM uses 32-bit Atom formats to store various types. 3-bits of the Atom describe the type data, leaving 29-bits for actual data. In some cases, like null/undefined/void/etc, we use 3-bits plus a few more bits to define the type.

For signed integers, we have 28-bits to work with plus a sign bit. For unsigned integers we have 29-bits (or maybe 28 with the upper bit always zero?). Once your number gets larger than 28/29 bits, we dynamically switch it to a Number Atom type, which contains a 3-bit type value with a 29-bit ptr. All ptrs are 8-BYTE aligned so we get away with using 29-bits there.

All three formats are basically interchangeable. When storing a number in an Atom, we see if it’s an integer and fits within the 28/29 bits. If so, we store it as a int/uint value – otherwise we store it as a Number value.

It essentially is an optimization for uint to make it faster at times but its good to know for large iterative loops or large storage where uints might be needed. This goes back to sometimes where optimizations are a mixed bag.  The switching/converting types adds delay to the iteration.

var num: uint;
for (var i: int = 0; i < 64; i++)
 num = 1 << i;
 trace( i, getQualifiedClassName( num ) );
0 int
1 int
2 int
3 int
4 int
5 int
6 int
7 int
8 int
9 int
10 int
11 int
12 int
13 int
14 int
15 int
16 int
17 int
18 int
19 int
20 int
21 int
22 int
23 int
24 int
25 int
26 int
27 int
28 Number
29 Number
30 Number
31 Number
32 int
33 int
34 int
35 int
36 int
37 int
38 int
39 int
40 int
41 int
42 int
43 int
44 int
45 int
46 int
47 int
48 int
49 int
50 int
51 int
52 int
53 int
54 int
55 int
56 int
57 int
58 int
59 int
60 Number
61 Number
62 Number
63 Number

9 Responses to “AS3 Interesting Numeric Storage Behavior”

  1. awflasher Says:

    Numbers are so strange in AS3 …

  2. drj11 Says:

    I don’t know the first thing about AS3, but I suspect that «1 << i» is the same as «1 << (i & 0x1f)». That is, only the bottom 5 bits of i are used to perform the shift, so the actual shift is always from 0 to 31 regardles of how large i gets.

    You don’t print out the value of num, but I suspect you’ll find that «1 << 1» is the same as «1 << 33». If so, it inherits this behaviour from the SHL instruction on Intel architectures.

  3. drawk Says:


    Yes it has to do with the underlying framework that runs probably in C or C++ that runs the virtual machine. This only happens when doing performance tweaks like bitwise shifts because it accesses the type faster due to direct memory but because there is no wrapper (I am speculating) then it passes the types back without any filtering.

    This does not happen on a normal loop with a typed iterator only performance areas where bitwise shifts are faster (which are in many places stop by polygonal labs to see that the cleanest code or simplest code is not always the fastest). Optimization can sometimes be a gotcha. Now on iterations using bitwise on a high performance app there will be slowdowns appearing in the range where Numbers appear rather than int. Again, not a big deal if you aren’t really looking to extend every bit of performance you can out of the flash vm, for most purposes its overkill. When doing games and other really high concurrent systems like that it becomes an issue. (i.e. iterating over objects in a multiplayer map rapidly)

  4. Nate Chatellier Says:

    It’s interesting, Sho claims that his tests led him to believe that Numbers may actually be faster than ints in Flash:

    Grant Skinner’s tests showed that ints had only a small improvement over Number, but uint was much worse then either:

    It seems like the only consistent claim is that numerical data types in Flash are inconsistent 😉

  5. drawk Says:

    Hey Nate,

    Yeh the uint constantly does conversions from int to Number so that is slower by far, conversions are expensive. The important thing is I guess is to go with one type and stick with it. Conversions are the bottleneck in uint when bitwise operations happen.

  6. Quantium Says:

    i’m agree Andre Michelle didn’t know about he talking about. but I thing this test is a little distorted. May be if you put entire data in trace, including num value. I did the test tracing the entire data and the result was this:

    var num: uint;

    for (var i: int = 0; i < 64; i++)
    num = 1 << i;

    trace( i, getQualifiedClassName( num ) , num);

    0 int 1
    1 int 2
    2 int 4
    3 int 8
    4 int 16
    5 int 32
    6 int 64
    7 int 128
    8 int 256
    9 int 512
    10 int 1024
    11 int 2048
    12 int 4096
    13 int 8192
    14 int 16384
    15 int 32768
    16 int 65536
    17 int 131072
    18 int 262144
    19 int 524288
    20 int 1048576
    21 int 2097152
    22 int 4194304
    23 int 8388608
    24 int 16777216
    25 int 33554432
    26 int 67108864
    27 int 134217728
    28 Number 268435456
    29 Number 536870912
    30 Number 1073741824
    31 Number 2147483648
    32 int 1
    33 int 2
    34 int 4
    35 int 8
    36 int 16
    37 int 32
    38 int 64
    39 int 128
    40 int 256
    41 int 512
    42 int 1024
    43 int 2048
    44 int 4096
    45 int 8192
    46 int 16384
    47 int 32768
    48 int 65536
    49 int 131072
    50 int 262144
    51 int 524288
    52 int 1048576
    53 int 2097152
    54 int 4194304
    55 int 8388608
    56 int 16777216
    57 int 33554432
    58 int 67108864
    59 int 134217728
    60 Number 268435456
    61 Number 536870912
    62 Number 1073741824
    63 Number 2147483648

    The Adobe Guys must to filter this issue, but in some way a programmer should understand this bad function in interpreted languages.

  7. stuart currie Says:

    BINGO! heres the theorm behind this pattern. see if you can spot why the answer you have is the cause of this. 0+1+1+2+4+8+16+32+64+128…etc

  8. Tenegri’s blog » Blog Archive » Are there real int and uint types? Says:

    […] Ryan Christensen: AS3 Interesting Numeric Storage Behavior Andre Michelle: Weird behavior of numbers in as3 Michael Baczynski: Bitwise gems – fast integer math Michael Baczynski: Int, uint and number data type conversion Sho Kuwamoto: Avoid ints in ActionScript Grant Skinner: Types in AS3: ints not so fast, uints slow! This entry was posted on Saturday, May 3rd, 2008 at 16:19 and is filed under Nincs kategorizálva. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. « ApplicationDomain – parent and child […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: