基于 javascript 函数的迭代的替代方案(例如 jQuery.each())

发布于 2024-08-05 09:25:43 字数 297 浏览 2 评论 0原文

我一直在观看 Google 技术讲座加速您的 Javascript 并讨论循环,演讲者提到要远离基于函数的迭代,例如 jQuery.each()(以及其他,在视频中的 24:05 左右)。他简要解释了为什么要避免它们,这是有道理的,但不可否认,我不太明白替代方案是什么。比如说,在这种情况下,我想迭代一列表格单元格并使用该值来操作相邻单元格的值(只是一个简单的示例)。谁能解释并给出基于函数的迭代的替代方案的示例?

I've been watching Google Tech Talks' Speed Up Your Javascript and in talking about loops, the speaker mentions to stay away from function-based iterations such as jQuery.each() (among others, at about 24:05 in the video). He briefly explains why to avoid them which makes sense, but admittedly I don't quite understand what an alternative would be. Say, in the case I want to iterate through a column of table cells and use the value to manipulate the adjacent cell's value (just a quick example). Can anyone explain and give an example of an alternative to function-based iteration?

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

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

发布评论

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

评论(5

对你而言 2024-08-12 09:25:43

如果您需要循环,那么简单的 for 循环应该会更快。

var l = collection.length;
for (var i = 0; i<l; i++) {
  //do stuff
} 

但是,仅仅因为它更快并不意味着它总是很重要。

它在客户端运行,而不是在服务器上运行,因此您无需担心用户数量的扩展,如果使用 .each() 很快,那么就保留它。但是,如果速度很慢,for 循环可以加快速度。

Just a simple for loop should be quicker if you need to loop.

var l = collection.length;
for (var i = 0; i<l; i++) {
  //do stuff
} 

But, just because it's quicker doesn't mean it's always important that it is so.

This runs at the client, not the server, so you don't need to worry about scaling with the number of users, and if it's quick with a .each(), then leave it. But, if that's slow, a for loop could speed it up.

终遇你 2024-08-12 09:25:43

古老的 for 循环

Ye olde for-loop

十年不长 2024-08-12 09:25:43

在我看来,基于函数的迭代会稍微慢一些,因为 1)函数本身的开销,2)创建和执行 N 次回调函数的开销,以及 3)额外的深度在作用域链中。然而,我想我应该做一个快速基准测试只是为了好玩。事实证明,至少在我的简单测试用例中,基于函数的迭代速度更快。这是代码和结果

测试基准代码

// Function based iteration method
var forEach = function(_a, callback) {
  for ( var _i=0; _i<_a.length; _i++ ) {
    callback(_a[_i], _i);
  }
}

// Generate a big ass array with numbers 0..N
var a = [], LENGTH = 1024 * 10;
for ( var i=0; i<LENGTH; i++ ) { a.push(i); }

console.log("Array length: %d", LENGTH);

// Test 1: function-based iteration
console.info("function-base iteration");
var end1 = 0, start1 = new Date().getTime();

var sum1 = 0;
forEach(a, function(value, index) { sum1 += value; });

end1 = new Date().getTime();
console.log("Time: %sms; Sum: %d", end1 - start1, sum1);

// Test 2: normal for-loop iteration
console.info("Normal for-loop");
var end2 = 0, start2 = new Date().getTime();

var sum2 = 0;
for (var j=0; j<a.length; j++) { sum2 += a[j]; }

end2 = new Date().getTime();
console.log("Time: %sms; Sum: %d", end2 - start2, sum2);

每个测试只是对数组进行求和,这很简单,但可以在某种现实生活场景中实际看到。

FF 3.5 的结果

Array length: 10240
function-base iteration
Time: 9ms; Sum: 52423680
Normal for-loop
Time: 22ms; Sum: 52423680

事实证明,基本的 for 迭代在此测试用例中速度更快。我还没有看过视频,但我会看一下,看看他是否在某些地方有所不同,导致基于函数的迭代变慢。

编辑:这绝不是最终的结果,只是一个引擎和一个测试用例的结果。我完全预计结果会是相反的(基于函数的迭代速度较慢),但有趣的是看到某些浏览器如何进行优化(可能或可能不是专门针对这种风格的 JavaScript),以便事实恰恰相反。

It seems to me that it would be case that function-based iteration would be slightly slower because of the 1) the overhead of function itself, 2) the overhead of the callback function being created and executed N times, and 3) the extra depth in the scope chain. However, I thought I'd do a quick benchmark just for kicks. Turns out, at least in my simple test-case, that function-based iteration was faster. Here's the code and the findings

Test benchmark code

// Function based iteration method
var forEach = function(_a, callback) {
  for ( var _i=0; _i<_a.length; _i++ ) {
    callback(_a[_i], _i);
  }
}

// Generate a big ass array with numbers 0..N
var a = [], LENGTH = 1024 * 10;
for ( var i=0; i<LENGTH; i++ ) { a.push(i); }

console.log("Array length: %d", LENGTH);

// Test 1: function-based iteration
console.info("function-base iteration");
var end1 = 0, start1 = new Date().getTime();

var sum1 = 0;
forEach(a, function(value, index) { sum1 += value; });

end1 = new Date().getTime();
console.log("Time: %sms; Sum: %d", end1 - start1, sum1);

// Test 2: normal for-loop iteration
console.info("Normal for-loop");
var end2 = 0, start2 = new Date().getTime();

var sum2 = 0;
for (var j=0; j<a.length; j++) { sum2 += a[j]; }

end2 = new Date().getTime();
console.log("Time: %sms; Sum: %d", end2 - start2, sum2);

Each test just sums the array which is simplistic, but something that can be realistically seen in some sort of real life scenario.

Results for FF 3.5

Array length: 10240
function-base iteration
Time: 9ms; Sum: 52423680
Normal for-loop
Time: 22ms; Sum: 52423680

Turns out that a basic for iteration was faster in this test case. I haven't watched the video yet, but I'll give it a look and see if he's differing somewhere that would make function-based iterations slower.

Edit: This is by no means the end-all, be-all and is only the results of one engine and one test-case. I fully expected the results to be the other way around (function-based iteration being slower), but it is interesting to see how certain browsers have made optimizations (which may or may not be specifically aimed at this style of JavaScript) so that the opposite is true.

瞄了个咪的 2024-08-12 09:25:43

最快的迭代方法是减少在循环中执行的操作。将内容从迭代中取出并最小化循环内的查找/增量,例如

var i = arr.length;

while (i--) {
   console.log("Item no "+i+" is "+arr[i]);
}

注意!通过在最新的 Safari(使用 WebKit nightly)、Chrome 和 Firefox 上进行测试,您会发现它确实没有无论您选择哪种类型的循环,如果它不是 foreachfor in(或者更糟糕的是,任何基于它们构建的派生函数)。

另外,事实证明,以下 for 循环比上面的选项还要快一点:

var l = arr.length;

for (var i=l; i--;) {
    console.log("Item no "+i+" is "+arr[i]);
}

The fastest possible way to iterate is to cut down on stuff you do within the loop. Bring stuff out of the iteration and minimise lookups/increments within the loop, e.g.

var i = arr.length;

while (i--) {
   console.log("Item no "+i+" is "+arr[i]);
}

NB! By testing on the latest Safari (with WebKit nightly), Chrome and Firefox, you'll find that it really doesn't matter which kind of the loop you're choosing if it's not for each or for in (or even worse, any derived functions built upon them).

Also, what turns out, is that the following for loop is very slightly even faster than the above option:

var l = arr.length;

for (var i=l; i--;) {
    console.log("Item no "+i+" is "+arr[i]);
}
挽清梦 2024-08-12 09:25:43

如果循环的顺序并不重要,那么以下应该是最快的,因为您只需要一个局部变量;另外,递减计数器和边界检查是用一条语句完成的:

var i = foo.length;
if(i) do { // check for i != 0
    // do stuff with `foo[i]`
} while(--i);

我通常使用的是以下内容:

for(var i = foo.length; i--; ) {
    // do stuff with `foo[i]`
}

它可能比以前的版本慢(后递减与预递减,forwhile),但更具可读性。

If the order of looping doesn't matter, the following should be fastest as you only need a single local variable; also, decrementing the counter and bounds-checking are done with a single statement:

var i = foo.length;
if(i) do { // check for i != 0
    // do stuff with `foo[i]`
} while(--i);

What I normally use is the following:

for(var i = foo.length; i--; ) {
    // do stuff with `foo[i]`
}

It's potentially slower than the previous version (post- vs pre-decrement, for vs while), but more readable.

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