Hi Iain,

I've been working a project quite similar to yours for a while now have 
encountered the same issues, particularly when handling large data sets 
(e.g. 1000+ items) with the Adobe Flex charting components, even if only 
a small subset is being displayed.

The core performance issue that I've found is that some parts of the 
charting framework, particularly the axes and transforms, utilize rather 
inefficient algorithms that scale poorly with increasing data set size. 
    As a result, while several series consisting of a handful of points 
can be drawn very quickly, the framerate becomes unacceptably slow if 
you are plotting multiple series consisting of hundreds of points of each.

For best performance with large data sets, you must either reduce the 
size of data that you're passing into the charts or replace these 
algorithms with more efficient implementations.  A lot of Adobe's code 
runs in O(n) or worse time.  You don't want this.  In my case, the 
solution isn't particularly pretty or fun.  I ended up with a blend of 
different approaches to reduce the total workload needed to calculate 
and render the charts.

First off, you'll realize the biggest gain by culling the number of data 
points passed to your chart(s), either by lowering the chart resolution 
with sparser data points or pre-culling the points that will not be 
displayed on the chart from its data provider rather than depending on 
the chart to do this via setting the minimum and maximum properties. 
The charting framework does not do this calculation in a very efficient 
manner, you're better off doing this yourself externally or overriding 
it in a subclass with a more efficient search scheme (e.g. a binary 
search tree).  The same is true for various other chart calculations, 
including the automatic calculation of minimum and maximum values for 
computing axial ranges--you can save quite a few cycles here if you can 
compute this more efficiently than iterating through the entire data 
provider (e.g. better selection algorithms).  Depending on how you're 
using the charting framework, you'll be best served by profiling your 
application using the Flex Profiler and looking for hotspots where you 
might be able to make overriding changes to reduce the magnitude of the 
calculation.

This being done, be very sure that you're not redrawing your charts more 
often than absolutely necessary.  This can't really be helped much if 
you're animating your chart, so you may want to reduce this to a minimum 
or perhaps drop down to a sparser data set when animating.  Also, if 
you're doing a lot of subclassing, be sure that you're only drawing what 
truly needs to be updated--in my case, I've found that my class may not 
always need a redraw even if it is notified as such.  In some cases, 
intelligent caching here may also help in reduce the computational load.

Last, if you need to do complex and time-consuming calculation loops 
that consume more than several dozen milliseconds or so (and will 
consequently pull down your framerate), consider breaking up your loop 
across multiple frames.  There are several ways you can do this, perhaps 
with a visitor pattern or by breaking out of your loop after so many 
iterations and storing your variables such that further execution can be 
resumed on the next frame.

Hope this helps,

Jim Cheng
EffectiveUI

Reply via email to