ActionScript2 性能:迭代对象属性

发布于 2024-07-11 21:36:48 字数 418 浏览 7 评论 0原文

迭代对象属性与迭代数组时是否会影响性能?

例如,使用对象:

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 的此类测量方法。

Is there a performance hit when iterating over object attributes vs. iterating an array?

Example, using objects:

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

Vs using an array

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

So - which is faster and most importantly by what factor?

IIRC, in some JavaScript implementation iterating over objects attributes is slower up to 20x but I haven't been able to find such measurement for ActionScript2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

昇り龍 2024-07-18 21:36:49

我刚刚尝试了一个非常相似的测试,但只迭代了 200k 个元素一次,结果相反:

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

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

我怀疑 Luke 的测试主要是循环开销,在数组情况下循环开销似乎更大。
另外,请注意,数组首先填充的时间要长得多,所以如果您的任务是插入繁重的,那就太好了。

此外,在我的测试中,将 arr.length 存储在局部变量中可测量到约 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");

I just tried a very similar test, but iterating just once over 200k elements, with opposite results:

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

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

I suspect Luke's test is dominated by loop overhead, which seems bigger in the array case.
Also, note that the array took significantly longer to populate in the first place, so ymmv if your task is insert-heavy.

Also, in my test, storing arr.length in a local variable gave a measurable performance increase of about 15%.

Update:

By popular demand, I am posting the code I used.

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");
小苏打饼 2024-07-18 21:36:49

好的。 为什么不做一些简单的测量呢?

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 由 Adob​​e 执行AVM1。

OK. Why not do some simple measurements?

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");

On my machine the array iteration is somewhat slower. This could be because ActionScript 2 doesn't have 'real' arrays but only associative arrays (maps). Apparently to work with an array the compiler has to generate some code overhead. I haven't looked into the specifics of this but I can imagine that that could be the case.

BTW. Doing this test might also show that putting the array length value into a variable doesn't really increase performance either. Just give it go....

UPDATE: Even though ActionScript and JavaScript are syntactically related, the underlying execution mechanism is completely different. E.g. FireFox uses SpiderMonkey and IE will probably use a Microsoft implementation whereas AS2 is executed by the Adobe's AVM1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文