Your test is not very good. Here's why:
getTimer
measures time, but cpu-time actually matters. If at some moment, for some reason the scheduler decides not to run the flash player, then you have less cpu-time within the same time frame. This is why results vary. It is the best you can use, but actually not much of a help if you're trying to track deviations of a few %.
- The deviation is really small. About 8%. Part of it stems from the effect described in point 1. When I ran the tests, results did vary in fact. 8% can come from anywhere. They may even simply depend on your machine, OS or minor player version or whatever. The result is just not signifficant enough to rely on. Also 8% speedup is not really worth consideration unless you find, there's a horrible bottleneck in your string processing that can be fixed by this or that trick with
RegExp
s
- Most imporantly: the difference you measure has nothing to do with regular expressions, only with everything else in the test.
Let my explain this in detail.
Try public function test7():void{}
. On my machine it takes about 30%-40% of the other tests. Let's have some numbers:
Running Tests
-------------------------------
Testing method: test1, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01716ms
Longest Iteration Time: 5ms
Shortest Iteration Time: 0ms
Total Test Time: 901ms
-------------------------------
Testing method: test2, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01706ms
Longest Iteration Time: 5ms
Shortest Iteration Time: 0ms
Total Test Time: 892ms
-------------------------------
Testing method: test3, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01868ms
Longest Iteration Time: 5ms
Shortest Iteration Time: 0ms
Total Test Time: 969ms
-------------------------------
Testing method: test4, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01846ms
Longest Iteration Time: 5ms
Shortest Iteration Time: 0ms
Total Test Time: 966ms
-------------------------------
Testing method: test5, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01696ms
Longest Iteration Time: 5ms
Shortest Iteration Time: 0ms
Total Test Time: 890ms
-------------------------------
Testing method: test6, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01696ms
Longest Iteration Time: 5ms
Shortest Iteration Time: 0ms
Total Test Time: 893ms
-------------------------------
Testing method: test7, 50000 iterations...
Test Complete.
Average Iteration Time: 0.00572ms
Longest Iteration Time: 1ms
Shortest Iteration Time: 0ms
Total Test Time: 306ms
-------------------------------
But Why? The following few things are expensive:
getTimer()
call to global functions (and static methods of other classes) is slow
(tester[methodName] as Function).apply();
- this is expensive as fuck. A dynamic property access requiring a closure creation, then a cast to an anonymous function and then invocation through apply. I couldn't think of a slower way to call a function.
var tester:RegExpTester = new RegExpTester();
- instantiation is expensive, since it requires allocation and initialization.
the following code will run signifficantly better. The overhead measured by test7
is reduced by factor 20 on my machine:
private function test(methodName:String, iterations:int = 100):void {
output("Testing method: " + methodName + ", " + iterations + " iterations...");
var start:Number = getTimer();
var tester:RegExpTester = new RegExpTester();
var f:Function = tester[methodName];
for (var i:uint = 0; i < iterations; i++) f();//this call to f still is slower than the direct method call would be
var wholeTime:Number = getTimer() - start;
output("Test Complete.");
output("\tAverage Iteration Time: " + (wholeTime / iterations) + "ms");
output("\tTotal Test Time: " + wholeTime + "ms");
output("-------------------------------");
}
again, some numbers:
Running Tests
-------------------------------
Testing method: test1, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01094ms
Total Test Time: 547ms
-------------------------------
Testing method: test2, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01094ms
Total Test Time: 547ms
-------------------------------
Testing method: test3, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01296ms
Total Test Time: 648ms
-------------------------------
Testing method: test4, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01288ms
Total Test Time: 644ms
-------------------------------
Testing method: test5, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01086ms
Total Test Time: 543ms
-------------------------------
Testing method: test6, 50000 iterations...
Test Complete.
Average Iteration Time: 0.01086ms
Total Test Time: 543ms
-------------------------------
Testing method: test7, 50000 iterations...
Test Complete.
Average Iteration Time: 0.00028ms
Total Test Time: 14ms
-------------------------------
so now the overhead is reduced to less than 1%, which makes it insignifficant (although in fact it can be reduced a lot more). However the deviation is now 16%. That's twice as much. And it's starting to look a little clearer. It is still insignifficant, IMHO, but actually it points to the two slowest methods: test3
and test4
.
Why would that be? Simple: Both methods create a new RegExp object (one using a literal, the other using the constructor). This consumes the time difference we can measure. The difference is bigger now, since before, per iteration you created 3 regular expressions (the two instance variables are initialized every time you instantiate a RegExpTester
). But the difference that is left now is that of creating 50000 RegExp
instances. Anything else is about equally fast.
If there's a conclusion to be drawn in answer to your question: There is no difference between literals or constructed RegExp
s. So I am afraid, the answer is: "It doesn't really matter, as long as you keep general performance optimization rules in mind.". Hope that helps.