tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/767-why-commands-are-so-slowRobotlegs: Discussion 2012-02-23T10:34:30Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-03T14:18:58Z2012-01-03T14:18:59ZWhy commands are so slow?<div><p>So, is it fast enough for your application? Or are these numbers
just to have numbers? While benchmarks are important, the real key
is, is it fast enough for <em>YOUR</em> application?</p>
<p>If you are building a game, then you probably don't want to be
using RL in your game's main loop. But for controlling the rest of
the game - view transitions between screens, backend
communications, setup/init of external data, etc etc, where speed
is perhaps not as critical, then you are golden.</p>
<p>My 2 cents.</p></div>jostag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-03T14:50:21Z2012-01-03T14:50:21ZWhy commands are so slow?<div><p>Thanks for your feedback, Raima.</p>
<p>I agree that that's a lot of overhead. The majority of that
probably<br>
comes from the Swiftsuspenders DI container that creates the
commands,<br>
whereas only a smaller part should be caused by Robotlegs
itself.</p>
<p>Which is why I went to great efforts to tune the performance
for<br>
Swiftsuspenders 2, which Robotlegs 2 will use.</p>
<p>Based on that, Robotlegs 2 should be a lot faster than 1. Once
it's<br>
properly optimized itself, that is. We didn't really do that, yet,
but<br>
Swiftsuspenders is already tuned as much as I know how to.</p>
<p>On top of these gains, it will be possible to use advanced
measures<br>
such as command instance pooling to further get the overhead
down.</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-03T16:03:18Z2012-01-03T16:03:18ZWhy commands are so slow?<div><p>jos - I need to stress test the tools and be able to "sell" them
for big games, at the moment with games I had to deal with I
imagine easily using a lot off commands per frame without getting
into main game loop.<br>
It's especially dangerous then you have to see application in
perspective. It have to be able to grow up to 2-3 years.</p>
<p>Till Schneidereit - that sounds great! I am waiting for ver.2
eagerly.</p>
<p>I wander is it possible to post-process application for
release.. something like swf optimization tool sometimes do.</p>
<p>Maybe it's possible to remove dynamic nature of injection with
post-processing application for release. Imagine... instead of
getting class definition dynamical every time you use it - it could
be done once by post-processing application. It would scan all
application classes and create with definitions about stuff that
has to be injected.</p>
<p>Is it something that would improve application execution...?</p>
<p>That leads me to another idea... is it possible to add extra
functions for injector, to let developers Create and add these
concrete classes with description what must be injected?<br>
so in situations there performance becomes a problem - developers
could remove stress from Swiftsuspenders DI, replacing it with some
manual work.</p></div>Deriltag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-03T16:13:41Z2012-01-03T16:13:41ZWhy commands are so slow?<div><blockquote>
<p>I wander is it possible to post-process application for
release.. something like swf optimization tool sometimes do.</p>
<p>Maybe it's possible to remove dynamic nature of injection with
post-processing application for release. Imagine... instead of
getting class definition dynamical every time you use it - it could
be done once by post-processing application. It would scan all
application classes and create with definitions about stuff that
has to be injected.</p>
</blockquote>
<p>That is certainly possible - but quite a lot of work.
Swiftsuspenders<br>
is already pretty complex and adding an ahead of time mechanism as
a<br>
build-time step would probably increase its complexity quite a
lot.<br>
That isn't to say that it'll never happen, but I don't think that
I<br>
will work on such a feature any time soon. Patches, on the other
hand,<br>
are very much welcome ;)</p>
<blockquote>
<p>Is it something that would improve application execution...?</p>
<p>That leads me to another idea... is it possible to add extra
functions for injector, to let developers Create and add these
concrete classes with description what must be injected? so in
situations there performance becomes a problem - developers could
remove stress from Swiftsuspenders DI, replacing it with some
manual work.</p>
</blockquote>
<p>You can do that in Swiftsuspenders 2 already: Simply create your
own<br>
DependencyProvider<a href=
"https://github.com/tschneidereit/SwiftSuspenders/blob/master/src/org/swiftsuspenders/dependencyproviders/DependencyProvider.as">1</a>
and let it create your instances the fastest way<br>
possible.</p>
<p>Here are two small samples:<br>
<a href=
"https://github.com/tschneidereit/SwiftSuspenders/tree/master/test/org/swiftsuspenders/support/providers">
https://github.com/tschneidereit/SwiftSuspenders/tree/master/test/o...</a></p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-03T16:38:10Z2012-01-03T16:38:10ZWhy commands are so slow?<div><p>I am reading it at the moment! (ver 1.6)</p>
<p>I see class description IS read once. Then data is stored to
m_injecteeDescriptions : Dictionary;</p>
<p>I will dig into the code!</p>
<p>thanks for time!</p></div>Deriltag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-04T15:06:19Z2012-01-04T15:06:19ZWhy commands are so slow?<div><p>There is always going to be overhead when introducing a
framework into your codebase, but when used properly that overhead
should be entirely negligible. A game (or application) that fires
off enough commands in a given frame for the impact to be
noticeable has something very wrong with its architecture.</p>
<p>Anything performance critical, like the game loop or rending
engine, should not be flowing through framework machinery.</p>
<p>Some examples of appropriate commands:</p>
<p>LoadUserProfileCommand<br>
LoadGameWorldCommand<br>
UnlockAchievementCommand</p>
<p>Some examples of very inappropriate commands:</p>
<p>FireBulletCommand<br>
CheckCollisionsCommand<br>
RenderFrameCommand</p>
<p>An application framework is designed to co-ordinate
collaboration between functional areas of your application, NOT to
actually do the work that those functional areas themselves should
be doing. I think that this is a big mistake that a lot of people
make.</p>
<p>That's not to say that we don't care about performance - we have
tried to keep things as lightweight as possible, and will create a
performance test harness for V2 to tune things further.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-04T15:53:09Z2012-01-04T15:59:36ZWhy commands are so slow?<div><p><a href=
"http://knowledge.robotlegs.org/discussions/questions/759-best-practice-for-rendering-in-a-tick-game#comment_12448482">
Here is another reply</a>, by Shaun, to a game-related
question.</p></div>Jostag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-05T11:22:24Z2012-01-05T11:22:24ZWhy commands are so slow?<div><p>"A game (or application) that fires off enough commands in a
given frame for the impact to be noticeable has something very
wrong with its architecture."</p>
<p>or.. it can be just a very big application. And even if you have
only 3-5 commands for main loop every tick... I can imagine many
random commands stack and have great impact to performance.
especial if you want to break it down to modules well.</p>
<p>I did a mistake with testing... testing it in debug mode.. :)
release boosts performance to 33 empty RobotLegs commands to eat up
1 ms of execution time.</p>
<p>This is still a bad number. And I am looking to options to
boosts it.</p>
<p>thanks for responses.</p>
<p>PS: there is no need to be hostile. I am not attacking your
Shrine of RobotLegs. Robotlegs is great! I love it!<br>
But I need to be skeptical and critical because applications that I
want to use it on has a high performance limitations, huge scope,
and involves lives of many people over course of couple years.</p>
<p>I will release results of my stress testing with code
shortly...</p></div>Deriltag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-05T11:32:28Z2012-01-05T11:32:28ZWhy commands are so slow?<div><blockquote>
<p>PS: there is no need to be hostile. I am not attacking your
Shrine of RobotLegs. Robotlegs is great! I love it!</p>
</blockquote>
<p>Sorry, I did not mean to sound hostile, that wasn't my intention
at all.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-05T13:14:47Z2012-01-05T13:14:47ZWhy commands are so slow?<div><blockquote>
<p>or.. it can be just a very big application. And even if you have
only 3-5 commands for main loop every tick...</p>
</blockquote>
<p>It's not about the size or complexity of the application. Firing
even a single application command on every tick is just not a good
idea. Again, please don't think I'm being hostile, these are just
my opinions, take it all with a pinch of salt.</p>
<blockquote>
<p>I can imagine many random commands stack and have great impact
to performance.</p>
</blockquote>
<p>I'm suggesting that if this happens then there is something
<em>very</em> wrong with the design of the application. Application
commands should not be tied to the game loop at all. Anything that
needs to happen on every tick should be happening elsewhere -
inside of an engine, module, or object.</p>
<p>When it's time to pause, load a new level or send data to a
server, then firing off a command to co-ordinate that task is
appropriate.</p>
<p>But updating game entities, detecting collisions and rendering
scenes are low-level implementation details that should not be
forced through an application framework. It doesn't matter how big
the application is, it's about working at the right level of
abstraction and using the right tools for the job.</p>
<p>For example, I have a huge application that has been in
development for a number of years. It has a bunch of commands, but
not that many. They exist to bootstrap the application and
co-ordinate its various sub systems.</p>
<p>Within that app there is a drawing tool that people can use to
draw pictures on photos. The drawing tool makes use of the Command
Pattern to provide undo/redo functionality. But those commands are
lightweight and do not involve the rest of my application in any
way. They are not dispatched on the application's event bus, they
are not injected with application dependencies, and nothing outside
of the drawing tool module even knows that they exist. Only when
it's time to actually do something with a drawing does the rest of
the application get involved.</p>
<p>The drawing tool should not know or care about what the
application does with a drawing after a user hits the save button.
And the application should not know or care about how the drawing
tool works internally. If the drawing tool dispatched events and
fired commands on the application's event bus then I would have
tightly coupled my application to the drawing tool, and for no good
reason.</p>
<p>But that's enough about all of that. Benchmarking is fun and
when you release your results I'll certainly check them out. I'm
sure you know all of this already, but please be sure to take the
usual things into account when benchmarking: running multiple
iterations to get min, max, and deviation values, garbage
collection interference, system instability, warmup etc. <a href=
"http://gskinner.com/blog/archives/2010/02/performancetest.html">http://gskinner.com/blog/archives/2010/02/performancetest.html</a></p>
<blockquote>
<p>For comparison : you can call object function 90.000 times per
ENTER_FRAME to use execution time.</p>
</blockquote>
<p>Exactly! Which is why you should be calling a method instead of
executing a command :)</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-06T21:44:10Z2012-01-06T21:44:10ZWhy commands are so slow?<div><p>My post with performance testing:</p>
<p><a href=
"http://www.mindscriptact.com/robotlegs-vs-puremvc-performance-battle/">
http://www.mindscriptact.com/robotlegs-vs-puremvc-performance-battle/</a></p>
<p>Thanks for your help.</p></div>Deriltag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-07T00:32:22Z2012-01-07T00:32:22ZWhy commands are so slow?<div><p>Coolio, I've replied on your blog (I tweaked your tests a
bit).</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-09T11:44:32Z2012-01-09T11:45:23ZWhy commands are so slow?<div><p>to Shaun : you hit the right spot with you tweaks!</p>
<p>So.. empty command uses ~0.007 ms! * every inject costs ~0.003
ms.</p>
<p>Making extending Command a very poor choice for your command
creation<br>
as it has 5 Injects and none of them are used extensively. (not in
my practice at least..)</p>
<p>contextView:DisplayObjectContainer .. as I mentioned in one of
previous posts... this one is almost never used...<br>
injector, commandMap, mediatorMap is needed for set-up commands...
and almost nowhere else?<br>
(I guess commandMap is exceptional... needed for executing other
commands...) eventDispatcher - also rarely used. In most cases I
let Models do the talking.</p>
<p>I imagine you would use ~3 injections per command on average...
so it's still slow.. but three time less then I initially thought
it will be.</p>
<p>Thanks!</p></div>Deriltag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-09T15:28:46Z2012-01-09T15:28:46ZWhy commands are so slow?<div><p>Yeh, I don't think we'll have those abstract classes (Command,
Actor etc) in RL2 - people tend to make their own abstract classes,
and as you pointed out, the various injected dependencies are
hardly ever actually used anyway.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-10T00:56:38Z2012-01-10T00:56:38ZWhy commands are so slow?<div><p>@deril: Any chance you'll update your post with the new stats?
Otherwise, if you feel that it's fair because most people probably
extend mvcs.Command, I understand. In that case, could you at least
add a "Command with no dependencies" row?</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-10T11:02:57Z2012-01-10T11:03:50ZWhy commands are so slow?<div><p>post updated... (sorry for delay... I am preparing RobotLegs
workshop...)</p>
<p>in any case... my conclusions is not changed. It's just commands
are not that bad as I thought it is.</p>
<p>oh... and I updated and cleaned the code...</p></div>Deriltag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-10T11:26:39Z2012-01-10T11:26:39ZWhy commands are so slow?<div><p>Aha, excellent!</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-11T17:58:00Z2012-01-11T17:58:00ZWhy commands are so slow?<div><p>Hm... more I dig into this.. more I want to know MORE! :)</p>
<p>I want to know why every line of RobotLegs and swiftsuspender is
written.. :) and it's not always easy to understand... and not
having RobotLegs v2 code does not help..</p>
<p>in any case - I have feeling that it is very bloated. Have a
look here : <a href=
"http://www.mindscriptact.com/blogFiles/frameworkTests/RobotLegsCommandFunctionStack.txt">
http://www.mindscriptact.com/blogFiles/frameworkTests/RobotLegsComm...</a>
this is a log of 2 empty commands running... it's huge!!</p></div>Deriltag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-11T21:58:48Z2012-01-11T21:58:48ZWhy commands are so slow?<div><p>Hi Deril,</p>
<p>sorry for jumping into the discussion this late.</p>
<p>Please have a look at the RL2 source here:<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/tree/version2/">https://github.com/robotlegs/robotlegs-framework/tree/version2/</a><br>
The contained version to of Swiftsuspenders can be found here:<br>
<a href=
"https://github.com/tschneidereit/SwiftSuspenders/">https://github.com/tschneidereit/SwiftSuspenders/</a></p>
<p>Right now, that new version isn't that optimized, causing the
overhead<br>
of command invocations to be even bigger than in RL1. I have a<br>
prototype of a hacked version of the command map that reduces
that<br>
overhead and brings it to within 30% to 50% of PureMVC's.</p>
<p>The more important point, though, is that that overhead buys you
a<br>
drastically reduced amount of coupling between the different
actors.<br>
Not only can you use anything that has a public
<code>execute</code> method as a<br>
command, you also don't need a central <code>facade</code> or any
other<br>
singletons, for that matter. And you can inject into your
command<br>
whatever you need (and have mapped in your context, of course)
without<br>
having to have that knowledge carried through several different
layers<br>
of the framework.</p>
<p>As you note, that decoupling comes with the price having a lot
of<br>
indirection (and thus overhead and long stacktraces). To some
extent,<br>
that will be reduces in RL2, but mostly, it's the price you have
to<br>
pay. In cases that where that is too high, Robotlegs simply isn't
the<br>
right tool for the job. But here I very much agree with Shaun:
In<br>
those cases, it's extremely likely that it's not the right job
for<br>
other reasons anyway and you should seriously look into entity<br>
frameworks like Ember2 or something else altogether.</p>
<p>Having said all that, I'd of course be very interested in any
changes<br>
we could make to improve performance. For Swiftsuspenders 2, I
tried<br>
my very best to shave off every bit of overhead I could, but maybe
I'm<br>
missing some major pieces.</p>
<p>cheers,<br>
till</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/126250132012-01-12T01:39:32Z2012-01-12T01:39:32ZWhy commands are so slow?<div><p>Hey Deril,</p>
<p>Most of the stacktrace comes from the automated dependency
injection side of things. Analysing a class and finding and
resolving its dependencies is fairly complex. But what's actually
happening here is that we're shifting work from the developer to
the machine.</p>
<p>C is faster than Ruby, but I'd much rather write Ruby and let
the machine do all of the boring work while I focus on actually
delivering a product. The same principle applies here.</p>
<p>For the shortest stacktrace possible you could simply do
this:</p>
<pre>
<code>new SomeCommand().execute();</code>
</pre>
<p>But that wouldn't be very convenient. You have to weigh up
convenience and development speed with raw execution speed.
Personally, I'm fine with letting the machine do what it's good at
if it let's me build my applications more quickly, reduces
boilerplate, and reduces the number of bugs I might introduce if I
did everything manually.</p>
<p>Again, that's not to say that we don't care about performance at
all. We do keep a close eye on performance. But, it's important to
keep things in perspective. Executing a piece of code that does
hardly anything at all is obviously going to have a shallower
stacktrace than executing a piece of code that does a lot of boring
work that I'd rather not do myself.</p>
<p>However, after saying all that, it's still useful having you
look into these things. When we start optimising the performance of
RL2 it will be handy to have these stats and benchmarks to look
back at.</p></div>Shaun Smith