Jon and I have posted Episode 3 of the Drunk on Software video podcast. In this episode we talk about some of the real world performance issues with Flex’s ArrayCollection. We’ve also created a few demos which illustrate how in some cases ArrayCollection is 26 times slower than Array:
- Instancing Array vs ArrayCollection Performance (view source)
- Adding items to Array vs ArrayCollection Performance (view source)
Let us know what you think.


16 Comments
Can you guys make those into video podcasts so we can subscribe to them like RIA Weekly
Ever try this?
var data:Array = getDataFromSomewher();
// dgAC – ArrayCollection bound to a DataGrid
for each ( var tmp:MyDomainObject in data ) {
dgAC.source.push( tmp );
}
dgAC.refresh();
This will add the stuff from ‘data’ into the Array that the ‘dgAC’ ArrayCollection wraps without firing events. Then the call to ‘refresh’ fires off an event telling whoever is listening that the contents changed!
Ever try that??
Hi codecraig,
I’ve done that in some instances. The problem however is that when AMF data is deserialized it is very hard to do that. And this also doesn’t solve the problem that instancing a ton of ArrayCollections still takes a long time (which AMF serialization also does when the data set contains a lot of collections). So certainly that will work sometimes. But in the case of AMF being deserialized, aside from custom deserializers, we have little control over how the data is deserialized and ArrayCollection is the default.
-James
James, can you provide a in-depth explanation on why an arrayCollection is 26 times slower, or is that already documented?
Hi Justin,
I don’t totally know why it is so much slower than an Array. But if you vote for the bug then hopefully someone will look further into it.
-James
Hi Wade,
We are looking into how to best do that. Do you use iTunes or just a plain old RSS reader for those?
-James
I am not a very technical person i just use itunes.
Perfect then. We will probably be switching to blip.tv which has iTunes support.
Have you tried creating the array and assigning the arrayCollection.source to this newly created array and publishing the change of the array collection with ArrayCollection.refresh(). This should get you very very close to Array insert speeds and still give you the events that we so much like with the ArrayCollection. From what I’ve seen the ugliness is in ArrayList with addItem. Event though the ArrayCollection has disableAutoUpdates that just ensures the auto updates are not fired via the ArrayCollection, but since the ArrayList fires events to the ArrayCollection the array collection just doesn’t pass this update along and is still listening when disableAutoUpdates has been activated. If you use this method you shouldn’t have ugliness with the ArrayCollection, if you have something coming from a server (and I believe there is a different kind of list that is created from a server side that replaces the ArrayList) you can have it transported as an Array and then assign the array to .source of an ArrayCollection or hope for the best that the implementation of the ArrayCollection’s list implementation is different or that it doesn’t use addItem/addItemAt.
I never got a real life situation where I need 100.000 Array instances? Do you? I think a more realistic benchmark would be with 1000 object, and for shure that are many objects.
Greetz
Alex
Hi Bruce,
See the comment above. The problem is that you have very little control over how AMF collections are deserialized.
-James
Hi Alex,
You might not be using large datasets and complex objects graphs but there are certainly many out there who do. My friend Jon encountered this problem on a real project.
-James
Okay, so I’m not sure which you’re trying to prove. 1) ArrayCollection vs Array performance is vastly different or 2) The flex serialization engine does not perform as well for Arrays as it does for ArrayCollections? or are you saying because the addItem on ArrayCollection is slow then all operations on the ArrayCollection are slow?
if 1, i think we can safely say you can use the source array element (when you have large datasets) and get a close comparison of the performance an array gets you.
if 2, then you should investigate whether there is performance issues with ArrayCollection serialization vs Array serializations. I would bet you would be quite amazed that the underlying serialization method of readExternal doesn’t use addItem or addItemAt but probably serializes the source data which is actually most likely an array. I would bet the ArrayList is even like this.
So I did a performance test based upon your code but changed the addItem to the .source = myA, then I added the writeObject & readObject of the data. And wouldn’t you know it it’s about 65 millis difference between the two.
Anyway I’m posting the updated source code
<![CDATA[
var i:int;
myA = [];
myAC.removeAll();
myACNAU.disableAutoUpdate();
myDBAC.removeAll();
myDDBAC.removeAll();
var startTime:Date = new Date();
var b:ByteArray = new ByteArray();
if( useA.selected )
{
for( i = 0 ; i < numObjects.value ; i++ )
{
myA.push({prop1:’asdf’, prop2:startTime, prop3:i});
}
b.writeObject(myA);
}
else if( useAC.selected )
{
for( i = 0 ; i < numObjects.value ; i++ )
{
myA.push({prop1:’asdf’, prop2:startTime, prop3:i});
}
myAC.source = myA;
myAC.refresh();
b.writeObject(myAC);
}
else if( useACNAU.selected )
{
for( i = 0 ; i < numObjects.value ; i++ )
{
myA.push({prop1:’asdf’, prop2:startTime, prop3:i});
}
myACNAU.source = myA;
myACNAU.refresh();
b.writeObject(myACNAU);
}
else if( useDBAC.selected )
{
for( i = 0 ; i < numObjects.value ; i++ )
{
myA.push({prop1:’asdf’, prop2:startTime, prop3:i});
}
myDBAC.source = myA;
myDBAC.refresh();
b.writeObject(myDBAC);
}
else if( useDDBAC.selected )
{
for( i = 0 ; i
@James Ward
@Bruce
The scenario in which the problem was discovered is a very large project with thousands of classes in an object graph. When an initial request at application startup is made to the server hundreds of thousands of objects are turned into AMF and sent back to the Flex applications. The deserialization was taking a very long time on the client. The reason turned out to be the amount of time it takes to instantiate and add items to ArrayCollections. Arrays are much faster but require a lot of extra work to deal with. There is not a good way to specify which collections should use Arrays and which should use ArrayCollections. Also creating custom serialization (read/write External) would be way too much work. Ideally Flex would deal with this scenario in a more efficient manner.
-James
Hi James,
First off, thank you for sharing. – Second, I am totally confused when it comes to AMF. Unfortunately, I don’t have the option of installing additional software such as LCDS, BlazeDS, OrbWeb, etc… so there is no way for me to test AMF that I am aware of.
I built a simple reporting app for my department. Presently, I use the webservice component and hook it up to a .NET webservice. Depending on the webservice it will return either an ArrayList of objects or a DataTable. In either case, Flex populates an Array (ArrayList) and an ArrayCollection(DataTable) which is then used for databinding. My questions to you are …
1. ArrayList or DataTable – which would you prefer when using/not using AMF?
2. Is my approach correct? If not, what approach would you take? Using my approach, which would yield better results – with/without AMF?
3. When creating an app with features such as friends list, photo sharing, etc…. would you recommend using Flex? If so, with/without AMF, and using an array or arrayCollection?
Hi Joey,
XML works fine when you have small data sets and do not control what is on the other side. In this case I’d stick with what works best which is probably Flex with ArrayCollections.
-James