Ваш тест не очень хорош. И вот почему:
getTimer
измеряет время, но время процессора действительно имеет значение. Если в какой-то момент по какой-то причине планировщик решит не запускать флэш-плеер, у вас будет меньше процессорного времени за тот же период времени. Вот почему результаты варьируются. Это лучшее, что вы можете использовать, но на самом деле не очень помогает, если вы пытаетесь отслеживать отклонения на несколько%.
- Отклонение действительно мало. Около 8%. Отчасти это связано с эффектом, описанным в пункте 1. Когда я проводил тесты, результаты действительно отличались. 8% могут прийти откуда угодно. Они могут даже зависеть от вашей машины, ОС или версии вспомогательного плеера или чего-либо еще. Результат не настолько важен, чтобы на него можно было положиться. Кроме того, ускорение на 8% не стоит учитывать, если только вы не обнаружите, что в вашей обработке строк есть ужасное узкое место, которое можно исправить тем или иным трюком с помощью
RegExp
s
- Самое важное: измеряемая вами разница не имеет ничего общего с регулярными выражениями, а только со всем остальным в тесте.
Позвольте мне объяснить это подробно.
Попробуйте public function test7():void{}
. На моей машине это занимает около 30% -40% других тестов. Давайте немного чисел:
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
-------------------------------
Но почему? Следующие несколько вещей стоят дорого:
getTimer()
медленный вызов глобальных функций (и статических методов других классов)
(tester[methodName] as Function).apply();
- это дорого. Доступ к динамическому свойству, требующий создания замыкания, затем приведение к анонимной функции и затем вызов через apply. Я не мог придумать более медленный способ вызова функции.
var tester:RegExpTester = new RegExpTester();
- создание экземпляра стоит дорого, поскольку требует выделения и инициализации.
следующий код будет работать значительно лучше. Служебная нагрузка, измеренная с помощью test7
, на моей машине уменьшается на в 20 раза:
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("-------------------------------");
}
опять несколько цифр:
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
-------------------------------
так что теперь накладные расходы уменьшены до менее чем 1%, что делает их незначительными (хотя на самом деле их можно уменьшить намного больше). Однако сейчас отклонение составляет 16%. Это вдвое больше. И это начинает выглядеть немного яснее. Это все еще незначительно, ИМХО, но на самом деле оно указывает на два самых медленных метода: test3
и test4
.
С чего бы это? Просто: оба метода создают новый объект RegExp (один использует литерал, другой - конструктор). Это потребляет разницу во времени, которую мы можем измерить. Теперь разница больше, так как раньше на каждую итерацию вы создавали 3 регулярных выражения (две переменные экземпляра инициализируются каждый каждый раз, когда создается экземпляр RegExpTester
). Но разница, которая осталась сейчас, заключается в создании 50000 RegExp
экземпляров. Все остальное примерно одинаково быстро.
Если в ответ на ваш вопрос необходимо сделать вывод: нет различий между литералами или построенными RegExp
с. Поэтому я боюсь, что ответ таков: «Это не имеет значения, если вы помните общие правила оптимизации производительности». Надеюсь, это поможет.