Massive performance problem with Robotlegs--need advice

RichSad's Avatar

RichSad

25 Mar, 2010 05:36 PM

Hi. We chose robotlegs for a new version of our product. The previous version used cairngorm. The robotlegs version is so slow it is totally unusable. We stripped the code down to a loading our data into its graph and compared it to the same functionality on the cairngorm side. The performance difference was staggering. I've seen the discussions of as3 signals and LazyMediation, but I am confused why there should be such a massive performance difference between the two platforms. We aren't talking about a little slower, we are talking about something like a 3-5X difference in performance. We aren't doing anything fancy, we are just loading some data into ByteArrays that are feeding a couple of custom graph types. In fact the graph code is the same in the both cases (they use the same SWC).

Our experiments seem to indicate that when dragging a cursor (a line representing time along a graph) the performance is a function of what is behind that cursor. In other words if we don't draw the graphs underneath the cursor drags fine, if we do draw the graphs the cursor is unusable. The same cursor in the Cairngorm version works fine whether the data is drawn below it or not.

We are close to having to abandon Robotlegs and lose several weeks progress unless we can figure out why this is happening. What on earth could explain the performance difference between the versions of the code with different MVCS frameworks?

  1. Support Staff 1 Posted by Shaun Smith on 25 Mar, 2010 06:20 PM

    Shaun Smith's Avatar

    Automatic mediation is most likely the cause of the performance degradation. Whilst convenient and appropriate for many Flex apps, it does incur a performance hit under certain circumstances. We currently employ the cheapest algorithm possible, but sometimes it's still too expensive.

    There are a couple of options for apps where performance is critical:

    1. Toggle the MediatorMap's enabled property. Set enabled to false to turn off the stage listeners when you don't need them. This can be managed, for example, via commands - during set-up phase leave the enabled property on, and turn it off after set-up is complete. Toggle as appropriate during distinct phases of your apps life-cycle. This option is fairly painless, but does require some planning with regards to "phases".

    2. Turn auto-mediation off (again by setting enabled to false on the MediatorMap), and manually create (by calling mediatorMap.createMediator(view)) and remove your mediators. This will probably require quite a bit of work - you'll need to find all the spots where you add your view components to stage and add the corresponding createMediator call.

    3. Use the LazyMediator utility. This requires swapping out the default MediatorMap for the lazy map, and adding a "trigger" to the constructors of your view components. Instead of inspecting every single display object that lands on stage, the view components themselves explicitly request mediation. More info: http://github.com/eidiot/robotlegs-utilities-LazyMediator

    Please let me know what option you decide to try and how it goes. I'll do my best to help.

    BTW, does your app make any use of the ViewMap?

  2. 2 Posted by Stray on 25 Mar, 2010 06:22 PM

    Stray's Avatar

    Hi Rich,

    I'm not the right person to answer this, but just wanted to ask a couple of questions:

    1) You're comparing non-debug performance in both cases?

    2) If the underlying graph code is the same in both cases, what functionality is robotlegs handling in your app?

  3. 3 Posted by RichSad on 25 Mar, 2010 07:44 PM

    RichSad's Avatar

    Hi Shaun and Stray,

    Thanks for the responses. I will give some of your suggestions a try and let you know. My partner on this project is currently trying some experiments related to comparing the two frameworks.

    We're not sure how to use Lazy Mediators with instances of objects declared in the mxml code. To the best of my knowledge, you can't get at the constructors for those objects. At the moment, the views we are debugging are indeed first declared in mxml as they are part of the default view that first shows up. It would be ideal if we could continue using mxml for some of our layout, although some parts of the app use AS3 code to create the views.

    To answer Stray's questions, we have done some testing both in debug and non-debug. To a lesser extent we have also looked at Windows vs Mac. We do development in Mac but the program runs on both. As you would expect, non-debug Windows is the fastest performance.

    Question 2 is an excellent question. Robotlegs provides the application framework. There are a number of views, videos, graphs, summaries... Our apps are written in an MVC manner. I selected Robotlegs to replace Cairngorm so that we could use Dependency Injection. I find DI much cleaner than singleton ApplicationModel.getInstance() type kludges. We also hope to integrate a unit testing framework shortly which also benefits from DI. At the moment the full answer to your question of "what functionality is robotlegs handing" is "not much yet".

    The app we're working on is the next generation of a currently shipping application that comes with our Q Sensor. Our company makes products that measure human emotions (or more accurately "human affective response") and this is the new viewer for the FaceSense product. Our company spun out of MIT Media Labs and has core technology based on MIT's iCalm and FaceSense.

  4. Support Staff 4 Posted by Joel Hooks on 25 Mar, 2010 07:47 PM

    Joel Hooks's Avatar

    is it possible for you to reproduce the behavior you are experiencing in a digestible sized example? I know that I don't just speak for myself in saying we'd like to get to the bottom of your issues.

  5. 5 Posted by Stray on 25 Mar, 2010 07:51 PM

    Stray's Avatar

    Hi Rich,

    If robotlegs isn't handling much then I think Shaun has hit the nail on the head - lots of children coming and going from the displaylist as your graph scrolls could well be causing a jam in the MediatorMap as it attempts to process those jams.

    I'm afraid I'm AS3 only so I can't help with the lazy mediators / mxml issue - but I'm wondering whether you can use the other tactic - listen on the view itself to find out when it's being added - to fire the relevant event so it gets mediated. I would normally do that via a constructor though.

    Or - as Shaun said, manually register your mediated views, if they themselves aren't being added and removed in abundance.

  6. Support Staff 6 Posted by Shaun Smith on 25 Mar, 2010 08:03 PM

    Shaun Smith's Avatar

    I believe that it should be possible to hook up the LazyMediatorActivator in MXML like so:

    <s:Component preinitialize="new LazyMediatorActivator(this)" ...>

    Ideally we need to make an MXML-friendly version of the Activator - one with setters instead of constructor arguments.

  7. 7 Posted by Rich Sadowsky on 25 Mar, 2010 08:05 PM

    Rich Sadowsky's Avatar

    Hi it's me (used my full name versus my "handle"). Wow, thanks for all the helpful responses. I am not sure how easy it would be to make a bitesized sample that shows the problem, because there is a ton of data involved. The problem doesn't present itself on small data sets. We first saw it when we started loading in hour+ measurements of people's emotional state. But I think we are circling in on a solution.

    I tried very quickly simply going into the event handler that is called after the data is loaded and graphed. At that point I just added:

    mediatorMap.enabled = false;
    

    and then proceeded to test dragging the cursor around. Voila! The performance was significantly improved. I will need to review this further and come up with a strategy for how to handle enabling/disabling mediation. I may leave that to our UI expert (I am more of a manager/architect/systems level programmer).

    Since we do use mxml objects I may try to find a way to basically accomplish lazy mediation without being able to add code to the constructor. OR possibly we can add code to the constructor of a class and then derive our higher level classes from it. Alternatively we could create an interface that implements a postContructor method that by convention we always call before doing anything else with an instance of those classes. Oh, I see Shaun just posted something about using mxml and constructors...

    Any further ideas are welcome. I really appreciate the rapid response. My confidence that we will solve this problem is growing by the minute!

  8. Support Staff 8 Posted by Shaun Smith on 25 Mar, 2010 08:23 PM

    Shaun Smith's Avatar

    Shew, glad to hear it! Switching to the LazyMediatorMap should have the same effect as setting enabled to false - without the complexity of deciding when and how to enable/disable.

  9. 9 Posted by Rich Sadowsky on 25 Mar, 2010 08:44 PM

    Rich Sadowsky's Avatar

    Thanks again Shaun. I am going to try out the Lazy Mediators, assuming they do work in mxml as you've suggested. My coding partner has the app back-ported to Cairngorm so we have a contingency plan. As you would expect, we are on a very tight timeline so we may have to go with the other framework for this demo/prototype/proof-of-concept project. But even if so we'll circle back to RL soon.

    Feel free (anyone) to chime in with other suggestions. It gave us great confidence to know how quickly and thoughtfully the three of you responded to my inquiries.

    If someone had the cycles to try and make a test case for this, the flow of app would be something like this:

    create an Adobe AIR project in flex
    create a view with one or two canvases
    load (or randomize) 100,000 to 1,000,000 data items into a ByteArray
    graph/display the points (type of graph doesn;t matter)
    Draw a cursor (vertical line) and position it at leftmost position (x=0)
    implement drag to allow the cursor to be dragged

    Notes:
    * we make ByteArray's of single precision Floats and populate using ByteArray.writeFloat(). Each float represents one frame of data (assume 25FPS)

    ** the Flex charting classes can't handle this much data so a custom class is needed. One of our "graphs" is very simple treating the data as binary and plots a line if true and none if false. A threshold decides what is "true"

    *** the dragging was the "straw that broke the camel's back". The performance was abysmal and unusable, even though the same code is in a shipping version of a previous version of our app that use Cairngorm. Prior to this we had numerous other performance concerns.

    I realize this is far from Hello World, but it appears the size of the dataset for the graph is a factor, since small data samples are OK. The app does not use a lot of memory, at least not a lot compared to Quick Hit Football (the previous app I wrote in Flex/AIR), and again I will point out that the other framework can deal with it fine. Overall, this is a pretty simple application currently in the grand scheme of things!

    Thanks again.

  10. Support Staff 10 Posted by Shaun Smith on 25 Mar, 2010 08:49 PM

    Shaun Smith's Avatar

    I took a quick stab at creating a more MXML-friendly activator:

    http://github.com/darscan/robotlegs-utilities-LazyMediator

    The activator can be declared in your view components, something like this:

    <LazyMediatorMxmlActivator view="{this}" />
    

    That would need to be in a Declarations block if you're using Flex4. Also, it's not tested so you might need to fork it and massage it a little.

  11. 11 Posted by Nikos on 14 Dec, 2010 01:29 PM

    Nikos 's Avatar

    Wouldn't the mediation bottleneck only occur if lots of things were being added and removed from the d list in the user workflow ?

  12. 12 Posted by Matt Karnas on 14 Dec, 2010 03:57 PM

    Matt Karnas's Avatar

    Rich,

    I know this conversation is several months old, but I am curious if you were able to implement Robotlegs or if you stuck with Cairngorm for your release.

    Thanks.

  13. 13 Posted by sadowsky on 14 Dec, 2010 04:04 PM

    's Avatar

    Hi. Thanks for asking. We had to go to Cairngorm since we didn't have time to experiment. It was sad since IoC/DI is so much of a better approach. Someday I may revisit this, but the lifecycle of that particular AIR application is probably approaching end of life.

  14. Stray closed this discussion on 11 Feb, 2011 10:45 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac