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







