Seems to be a bit of a current topic floating around on doing heavy work in Flex/AIR efficiently. If you have done any sort of data parsing or fetching large amounts of data with your UI in Flex or AIR you have undoubtedly been introduced to the Windows “Not Responding” message or the MAC spinning balloon thingy. Sure, your routine takes only 3 seconds to run, “so what is the issue?” you say. Well, 3 seconds is a long ass freakin time for one thing to occur uninterrupted in Flash. Consider Flex having a default frame rate of 24 frames per second. This leaves about 40 milliseconds, yes milliseconds, per frame. Even though Flex uses primarily one frame, this frame is re-entered every 40 milliseconds and Flesh re-draws what is needed. Thus you get that nice Halo effect showing up when you mouse over a Button for example. Running a procedure that takes 3 seconds is far longer then that 40 millisecond spot in the universe, eh? Thus Flash freaks and no UI updates are made resulting in what is known as UI degradation.
So, how do we get around this? Tell your client less information is better here, no one can really digest 100,000 points of light, eh? Common answer for sure and one that can make sense most of the time. Well, after your clients come back to you and say no way Jose, our users need to see 100,000 points of light, you begin to realize you just may have a data centric application and not a information centric one. A point to note here readers, there is a difference between information and data. What to do?
Enter the topics of threading, concurrency, and Mean Greenies. Well, maybe not the last item per se. Recently I had the pleasure of hearing Charlie Hubbard speak at our local Flex UG AFFUG. He spoke on Concurrency issues in Flash. He has a mondo in depth three part blog post on it here. Sure, he mentions the use of callLater() to break up your worker process and allow time for Flash to get to the next frame and redraw. Further mentioned using timers to achieve a similar goal. While both of these can work and get you on the path of righteousness, they are not so performant. Charlie’s approach was to address this by making better use of the time a frame exists before its great circle of life repeats itself. The skinny on this is to maximize the time alloted to a frame by measuring each step in your process, keeping stats on it, and deciding when to wait for the next frame to begin. Oh and giving Flash a itsy bitsy tiny bit of room to redraw itself and be happy. Ironically Jesse Warden recently blogged on this very same topic too.
This whole discussion centers around the idea of Green Threading. Green Threads are essentially scheduled batches of work-time in single threaded architectures. That is, in a single-threaded architecture like Flash, Green Threads are chunks of work you dedicate to a certain procedure(s), scheduled by Flash and your code. These are different then kernel level threads which are handled by the OS. Drew Cummins did some work a bit back on a Green Thread library for use in Flex. Charlie Hubbard added to this a bit and put his library out in Google Code land here. Check out his Mandlebrot Set example and see a virtual shite load of data points be drawn on screen.
What about AMF/Remoting you ask? I’ve found this croaks belly up with large Arrays, yes Array not ArrayCollection, of VOs. In my case the VOs had maybe five properties tops. Have you had better experience here? Please let me know!
Now, with all this stuff going on I decided to play around and build a rough little test app today in AIR using this library. I’ve put together a AIR app that consumes a 100k line CSV file, then concatenates it to be 300k lines. This concatenated CSV string is fed to four different cases: Loading into a array of 300k typed objects synchronously and then asynchronously and loading the same data into a SQLite table synchronously and then asynchronously. Times are output for comparison. Please notice some things while running the app. Both of the synchronous functions lock up the UI for a bit, you will notice right away mousing over the buttons does not show the Halo glow at all. The asynchronous functions do not lock the UI up, in fact, there is a progress bar displaying the progress LIVE! Timings for each are quite close without tweaking or tuning the settings Charlie has setup in the Green Thread library.
Go ahead and download the app here. The source is viewable by a simple right-click on the application. Please note that the CSV test file is included here, so the download is a bit large being 144MBs Enjoy!