Производительность ActionScript2: перебор атрибутов объекта - PullRequest
0 голосов
/ 27 января 2009

Есть ли снижение производительности при переборе атрибутов объекта по сравнению с перебором массива?

Пример использования объектов:

var x:Object = {one: 1, two: 2, three: 3};
for (var s:String in x) {
 trace(x[s]);
}

против использования массива

var a:Array = [1, 2, 3];
var len:Number = a.length;
for (var i:Number = 0; i < len; ++i) {
 trace(a[i]);
}

Итак - что быстрее и что наиболее важно по какому фактору?

IIRC, в некоторых реализациях JavaScript итерирование по атрибутам объектов выполняется медленнее до 20 раз, но я не смог найти такое измерение для ActionScript2.

Ответы [ 2 ]

1 голос
/ 28 января 2009

Я только что попробовал очень похожий тест, но итерировал только один раз более 200k элементов, с противоположными результатами:

Task build-arr: 2221ms
Task iter-arr: 516ms

Task build-obj: 1410ms
Task iter-obj: 953ms

Я подозреваю, что в тесте Люка преобладают издержки цикла, которые в случае массива кажутся больше. Кроме того, обратите внимание, что заполнение массива заняло значительно больше времени, поэтому ymmv, если ваша задача слишком тяжелая.

Кроме того, в моем тесте сохранение длины строки в локальной переменной дало ощутимое увеличение производительности примерно на 15%.

Обновление:

По многочисленным просьбам я публикую использованный код.

var iter:Number = 200000;
var time:Number = 0;
var obj:Object = {};
var arr:Array = [];

time = getTimer();
for (var i:Number = 0; i < iter; ++i) {
  arr[i] = i;
}
trace("Task build-arr: " + (getTimer() - time) + "ms");

time = getTimer();
for (var i:Number = 0; i < iter; ++i) {
  arr[i] = arr[i];
}
trace("Task iter-arr: " + (getTimer() - time) + "ms");

time = getTimer();
for (var i:Number = 0; i < iter; ++i) {
  obj[String(i)] = i;
}
trace("Task build-obj: " + (getTimer() - time) + "ms");

time = getTimer();
for (var i:String in obj) {
  obj[i] = obj[i];
}
trace("Task iter-obj: " + (getTimer() - time) + "ms");
0 голосов
/ 28 января 2009

OK. Почему бы не сделать несколько простых измерений?

var time : Number;

time = getTimer();

var x:Object = {one: 1, two: 2, three: 3};

for( i = 0; i < 100000; i++ )
{
    for (var s:String in x) 
    {
        // lets not trace but do a simple assignment instead. 
        x[s] = x[s];
    }
}

trace( getTimer() - time + "ms");

time = getTimer();

var a:Array = [1, 2, 3];
var len:Number = a.length;

for( i = 0; i < 100000; i++ )
{
    for ( var j : Number = 0; j < len; j++) 
    {
        a[j] = a[j];
    }
}

trace( getTimer() - time + "ms");

На моей машине итерация массива несколько медленнее. Это может быть связано с тем, что ActionScript 2 не имеет «реальных» массивов, а содержит только ассоциативные массивы (карты). По-видимому, для работы с массивом компилятор должен генерировать некоторые накладные расходы кода. Я не изучал специфику этого, но могу представить, что это может быть так.

КСТАТИ. Выполнение этого теста также может показать, что помещение значения длины массива в переменную на самом деле также не увеличивает производительность. Просто дай ему уйти ....

ОБНОВЛЕНИЕ: Несмотря на то, что ActionScript и JavaScript синтаксически связаны, базовый механизм выполнения совершенно другой. Например. FireFox использует SpiderMonkey , и IE, вероятно, будет использовать реализацию Microsoft, тогда как AS2 выполняется AVM1 от Adobe.

...