One of the most rarely used keyword in ActionScript 3 is definitely the 'with' keyword. Let's see what the documentation tells us about this keyword:
Establishes a default object to be used for the execution of a statement or statements, potentially reducing the amount of code that needs to be written.
You read more about 'with' keyword in documentation.
This looks promising, we do love the "write less, do more" concept, but how about performance of this solution? I've tested it by comparing multiple
this.graphics...
calls and 'with' keyword shortcut syntax. Enough writing, let's see what I came up with:private function withKeywordTest():void { var initialTime:int; var time:int; var i:int; var t:int; const loopCount:int = 100000; const testsCount:int = 10; time = 0; for(t = 0; t < testsCount; t++) { initialTime = getTimer(); for(i = 0; i < loopCount; i++) { with(this.graphics) { lineStyle(1); beginFill(0x000000); drawRect(0, 0, 10, 10); endFill(); clear(); } } time += getTimer() - initialTime; } log("With keyword: " + Math.round(time / testsCount) + "ms"); time = 0; for(t = 0; t < testsCount; t++) { initialTime = getTimer(); for(i = 0; i < loopCount; i++) { this.graphics.lineStyle(1); this.graphics.beginFill(0x000000); this.graphics.drawRect(0, 0, 10, 10); this.graphics.endFill(); this.graphics.clear(); } time += getTimer() - initialTime; } log("Code repetitions: " + Math.round(time / testsCount) + "ms"); }
The tests were taken 10 times each, ending result is a mean time in miliseconds:
Hardware | with keyword | code repetitions |
---|---|---|
2.1 Ghz Intel Core 2 Duo, Windows 7 Flash Player 10.1 Release | 108ms | 112ms |
this.graphics
. But as always, there is the other side of the coin - code within 'with' block isn't evaluated at compile time. That means if you change
with(this.graphics)
to with(this)
in my example, the code will compile just fine - of course you'll get runtime error, but lack of compile time checking can be a problem. I would suggest using 'with' keyword for common actions like programmatic drawing and other kind of jobs that can't suprise you.--- public static const UPDATE:String ---
A very kind man and a detective Jackson Dunstan gave me an advice to try to refine my tests using caching
this.graphics
getter value in a local variable. The idea was to show that 'with' block is in fact slower than normal code repetition. Here is refined test method:private function withKeywordLocalVariableTest():void { var initialTime:int; var time:int; var i:int; var t:int; const loopCount:int = 100000; const testsCount:int = 10; var g:Graphics = this.graphics; time = 0; for(t = 0; t < testsCount; t++) { initialTime = getTimer(); for(i = 0; i < loopCount; i++) { with(g) { lineStyle(1); beginFill(0x000000); drawRect(0, 0, 10, 10); endFill(); clear(); } } time += getTimer() - initialTime; } log("With keyword(local variable): " + Math.round(time / testsCount) + "ms"); time = 0; for(t = 0; t < testsCount; t++) { initialTime = getTimer(); for(i = 0; i < loopCount; i++) { g.lineStyle(1); g.beginFill(0x000000); g.drawRect(0, 0, 10, 10); g.endFill(); g.clear(); } time += getTimer() - initialTime; } log("Normal this.graphics repetitions(local variable): " + Math.round(time / testsCount) + "ms"); }
Hardware | with keyword (local variable) | code repetitions (local variable) |
---|---|---|
2.1 Ghz Intel Core 2 Duo, Windows 7 Flash Player 10.1 Release | 107ms | 102ms |
Those results using local variable caching in fact a little different. With keyword seems to be a slower solution. This definitely isn't bringing me closer to using 'with' keyword:)
3 komentarze:
It's good to see people interested in such esoteric areas of AS3 performance! :-D
I've written about some related articles about "with" block syntax, bytecode and performance before. My tests showed "with" to be about 6x slower than local variable access. Your test is using a getter field call (this.graphics), which is quite a bit slower than a local variable access. I think a fairer test would be to cache this.graphics as a local variable outside of the test loop and access the cached version instead. I'll bet you'll find the results radically different.
Thanks Jackson, it's good to see people reading this:D
Good point with getter, I'll try to run test with local variable caching and post update here. For now I can't convince myself to use "with" block on a regular basis, but I'm pretty sure it's great for rapid prototyping.
I've created 2nd test with local variable caching. You were right, "with" block seems to be slower but not as much as you've pointed out (6x).
Post a Comment