Reputation: 3368
If I serialize the exact analogous of an array and a vector into ByteArrays, I get almost twice the size for the vector. Check this code:
var arr:Array = [];
var vec:Vector.<int> = new Vector.<int>;
for (var i:int = 0; i < 100; ++i) {
arr.push(i);
vec.push(i);
}
var b:ByteArray;
b = new ByteArray();
b.writeObject(arr);
trace("arr",b.length); // arr 204
b = new ByteArray();
b.writeObject(vec);
trace("vec",b.length); // vec 404
Seems like a buggy or unoptimized implementation on Adobe's behalf..? Or am I missing something here?
Upvotes: 1
Views: 93
Reputation: 18747
According to AMF 3 specification AMF stores arrays as a separate, optimized for dense arrays manner, and also stores ints in an optimized manner to minimize the number of bytes used for small ints. This way, your array of values 0-99 gets stored as:
00000000 0x09 ; array marker
00000001 0x81 0x49 ; array length in U29A format = 100
00000003 0x01 ; UTF8-empty - this array is all dense
00000004 to 000000CB - integer data, first integer marker 0x04, then an integer in U29.
All your ints are less than 128, so they are represented as single byte equal to the integer. This makes a small int in an array take 2 bytes instead of full 4 or even 8 for large integers.
Now, for Vector, as Vector is dense by default, it's better to not convert an integer to U29 format, because anything bigger than 0x40000000 gets converted to DOUBLE (aka Number
) and this is bad for vectors, so a Vector.<int>
is stored as is, with 4 bytes per integer inside a vector.
00000000 0x0D ; vector-int marker
00000001 0x81 0x49 ; U29 length of the vector = 100
00000003 0x00 ; fixed vector marker, 0 is not fixed
00000004 to 00000193 - integers in U32
So, for small integers an array takes less space than a Vector of ints, but for large integers an array can take up to 9 bytes per int stored, while a Vector will always use 4 bytes per integer.
Consider the following alteration to your code:
var arr:Array = [];
var vec:Vector.<int> = new Vector.<int>;
for (var i:int = 0; i < 100; ++i) {
var x:int=Math.floor(Math.random()*4294967295); // 0 to 0xFFFFFFFE
arr.push(x);
vec.push(x);
trace(x);
}
var b:ByteArray;
b = new ByteArray();
b.writeObject(arr);
trace("arr",b.length); // some variable value will be shown, up to 724
b = new ByteArray();
b.writeObject(vec);
trace("vec",b.length); // here the value will always be 404
Upvotes: 2