SINGLE POST

FP10: Vector vs Array

Update 2 (Read first):

I noticed there are still some trackbacks to this post. To clear things a little bit up. This post is 2 1/2 years old and the Flash Player version used was one of the first (the first?) that supported Vector at all. The results of this tests are NOT VALID! any more. In general the tests are not completly wrong, but they do not fit into real-world scenarios.

Update

I have replaced the Sprite by an own class/object (SimpleObject with 3 public properties, x, y, z). The results are the same.

Vector vs Array

Started a little speed measurment with new Vector-type and the “old-fashioned” array. As everyone could read in the Adobe AS3 Docs, Vector should give us some advantages over Array iteration and data-access.

I have tried several test-settings and i was completely surprised by the results (in a bad way).

What i am most interested in, is fast access of objects. So i create a pool of object-references(simple sprite), one as an array and the other pool is defined as a Vector.<Sprite>.


var i:uint = 0;
 var n:uint = N_TEST; ( n = 20000000)
 var v:Vector.<Sprite>;
 v = this.objectPoolV;

var timestamp:int = getTimer();

i = 0;
 var r:Sprite;
 while (i < n)
 {
 r = v[i];

i++;
 }

result.htmlText += "<br />Result Vector Complex Operation Test: " + (getTimer() - timestamp);

This was my first test and the difference is noticeable (but look at n, how high it has to be for even get a small difference).

  • Vector result: 511 ms
  • Array result: 659 ms

But this is not a very commen use. So, next step was to save the reference in a locale variable and move the sprite in all 3 directions about 10px. I have done this test with and without an explicit cast.


var i:uint = 0;
 var n:uint = N_TEST;
 var v:Array;
 var r:Sprite;
 v = this.objectPoolA;

i = 0;

var timestamp:int = getTimer();
 while (i < n)
 {
 r = v[i];
 r.x += 100;
 r.y += 100;
 r.z += 100;

i++;
 }

result.htmlText += "<br />Result Array Complex Operation Test: " + (getTimer() - timestamp);
 

This result i have never expected, array is faster!! than the vector, but why? I am only referencing to the current dataset.

  • Vector result: 5118 ms
  • Array result: 4885 ms

If i cast the array, the result is worse than without a cast.

 r = Sprite(v[i]); 

I know, casting is expensive, but look at the results with casting.
<ul>
<li>Vector result: 7055 ms</li>
<li>Array result: 7126 ms</li>
</ul>
So, finally let’s have a look at the worst sample. Direct access of properties threw the Array and Vector.

 var i:uint = 0;
 var n:uint = N_TEST;
 var v:Vector.<Sprite>;
 v = this.objectPoolV;
 i = 0;
 var timestamp:int = getTimer();
 while (i < n)
 {
 v[i].x += 100;
 v[i].y += 100;
 v[i].z += 100;
 i++;
 }
 result.htmlText += "<br />Result Vector Complex Operation Test: " + (getTimer() - timestamp);
 

I have to reduce the N_TEST constant to 1000000, here are the results

  • Vector result: 1751 ms
  • Array result: 1631 ms

Is anyone able to confirm this results?

The complete testfile is downloadable here. (If you find a mistake, please tell me).


9 thoughts on “FP10: Vector vs Array

  1. I’m not sure that an access call or a screen write would be the thing to benchmark here. I don’t have non-public info on the vector type myself, but from reading it assumed it enabled a more parallel-like processing of data. But the references to it in the docs were oblique enough that I suspect we’ll know much more by time of final release.

    Glad it piqued your interest, though. ;-)

    cu, jd/adobe

  2. @jd: To be honest, i have no idea what is the right test for the “Vector”. In my opinion it’s a “typed” array, or like a Generic, and so my conclusio was to test if an object-access to a Vector is faster than it is with an Array.

    Array -> non-typed, has to be checked at runtime
    Vector -> typed, faster, no check for type

    I am happy enough, that i have a field which is typed now, but there was this little abstract about performance and Vector in the docs ;)

  3. Have you tried the test using primitives?

    Depending on what they are doing behind the scenes to create the the typed array, it could be that the only real performance benefit will occur when you use primitives.

    Derek

  4. @Derek: Have a lookt at the test-file, there are several tests with primitives (read, write, simple maths), sometimes advantages, but little.

  5. Not sure if you figured it out yet, but I found that if I auto-completed vector in flexbuilder it added:

    import __AS3__.vec.Vector;

    with that I found that my vector was VERY slow if I didn’t use a POD

    tick counts for processing an array of 10mill items
    first number set is vector, second is array
    first number is a normal forloop, second is for each

    for this test I casted the results for just the array forloop and left the vector naked:

    sum += vec_buff[i].foo;

    I made a small custom class that inherited from a small base class with a single public variable (foo)

    2552:1143 : 1512:1175

    as you can see a typed foreach loop is the same speed as an array, but a uncasted forloop is VERY slow.

    I did not experience this issue when I filled the arrays with PODs (uint for example)

    I just recently _removed_ that import, and am now getting numbers about the same speed as a casted array (slight, VERY slightly better) in the forloops

    Also note: easy way to detect if this is a problem, try to assign the vector element to an incorrect type, the imported version will NOT throw an error with strict type enabled, whereas the native version will (sum = vec_buff[i]; should throw an error but does not with imported version)

    I’m using Flex 3.3 lastest stable build

  6. Also I would like to note: the operator you use GREATLY affects your speeds, here’s an example using PODs (uint): (there is NO type casting in this at all)

    =
    150:559 : 219:459

    vs.

    +=
    147:592 : 834:459

    (code in the loops is the same as the last example, just in one test we’re assigning to sum, in the other test we’re adding to it)

    these are the performance numbers we expect from a strongly typed Vector vs. a normal Array as the compiler should be able to negate RTI (run-time type identification)

    Note: compiling against flex 3.3 and flex 4(most recent nightly) yielded no performance differences.