Wednesday, February 27, 2008

Flex Optimization: beware bindable VO's

We ran into a situation today in an application processing a large data set and seeing some really exhorbenant parsing times on the Flex side.  We're transferring the data using AMF and it's still taking up to 5 times longer to parse the data than transfer it (500 ms to transfer, up to 4.5 seconds to parse it.  Yikes!)

Part of the problem is that someone made a key VO bindable.  The data set we're loading is about 5,000 objects in size.  Each object gets parsed in a method that makes reference to properties on this vo at least 6 different times in a while loop which can loop hundreds of times depending on the data point.

When the VO is bindable, this means 6 different method calls, since bindable objects have their public properties replaced with getter and setter methods to support binding.  Having these calls made from inside the while loop lead to roughly 1 million excess method calls in parsing the data alone.

There are other inefficiencies in our data parsing yet to be found, but removing the "bindable"
tag on this object lead to an immediate 30% increase in speed.  Removing the tag hasn't had any noticable effects so far.  

It's likely someone wanted to bind to a data provider before the data had been created and then used the data object itself as part of an MXML tag.  Even though the data will never be updated and thus doesn't really need to be bindable, FlexBuilder can't tell that and produces a warning message asking that the object be bindable.  Clearning up this tiny warning had disastrous results, though we didn't find them until now. :)

Since the VO itself is never updated in our application, there's no reason it ever should've been bindable.  If you did need a bindable VO there are several ways to avoid our problem still.  First, we could've cached the VO's values outside of our while loop, operated on them within the loop, and then updated afterwards if necessary.  Second, we could've listened for a more general "loaded" event on the entire collection rather than binding to something on the individual VO's themselves, since they should all update at more or less the same time.

Finding performance bugs like this is key to enhancing user experiences in Flex.  I'd heard all of the standard performance enhancements before (type your variables, don't nest for loops, etc.) but hadn't heard anyone mention anything about binding before, so this was sort of a revelation for me even though it probably should've been obvious.

If you're suffering from performance degradation and can't figure out why, look at your binding.  Fire up that brand new shiny profiler and see how many times your bindable methods are being called - I bet it's more than you'd think.


Anonymous said...

Great post. Thanks.

A. said...

Faced the same issue and debugged ut. Though I did not take advantage of the profiler.

Have put up soem points to optmize the applciations here -