简体   繁体   English

为什么for-in的javascript速度很慢?

[英]Why is for-in slow in javascript?

I have read in several places that for-in loops are slower than looping over an array... Though I understand that moving forward in sizeof (type) blocks is practically effortless compared to whatever happens behind to the scenes to iterate over an object's keys, I am still curious, what the exact reason is that it's so slow... 我已经在很多地方读到了for-in循环比循环遍历数组要慢...尽管我了解到,与在场景背后进行迭代以遍历对象的键相比,在sizeof(type)块中前进实际上是毫不费力的,我仍然很好奇,确切的原因是这么慢...

Is it having to do a reverse hash function to get the key, and that process is what is slow? 是否必须执行反向哈希函数才能获取密钥,而这个过程很慢?

The real answer to this in the case of any particular engine will likely depend on that engine's implementation. 对于任何特定引擎,对此的真正答案很可能取决于该引擎的实现。 (As will the size of the difference, if any.) (如果有的话,差异的大小也会如此。)

However, there are invariants. 但是,有不变量。 For instance, consider: 例如,考虑:

var obj = {a: "alpha", b: "beta"};
var name;
for (name in obj) {
    console.log(obj[name]);
}

var arr = ["alpha", "beta"];
var index;
for (index = 0; index < arr.length; ++index) {
    console.log(arr[index]);
}

In the case of obj , the engine has to use a mechanism to keep track of which properties you've already iterated over and which ones you haven't, as well as filtering out the non-enumerable properties. 对于obj ,引擎必须使用一种机制来跟踪已迭代的属性和尚未迭代的属性,并过滤掉不可枚举的属性。 Eg, there's some kind of iterator object behind the scenes (and the way the spec is defined, that may well be a temporary array). 例如,幕后有某种迭代器对象(以及规范的定义方式,很可能是一个临时数组)。

In the case of arr , it doesn't; arr的情况下,它不是; you're handling that in your code, in a very simple, efficient way. 您可以以非常简单,有效的方式在代码中进行处理。

The content of the block of each loop is the same: A property lookup on an object. 每个循环的块内容相同:在对象上进行属性查找。 (In the latter case, in theory, there's a number-to-string conversion as well.) (在后一种情况下,理论上也有数字到字符串的转换。)

So I expect the only non-implementation-specific answer to this is: Additional overhead. 因此,我希望对此的唯一非特定于实现的答案是:额外的开销。

for..each loops use iterators and generators . for..each循环使用迭代器生成器

Iterator is an object that has a next() method. 迭代器是具有next()方法的对象。 Generator is a factory function that contains yield() expressions. Generator是一个包含yield()表达式的工厂函数。 Both constructs are more complicated than an integer index variable. 两种构造都比整数索引变量复杂。

In a typical for(var i = 0; i < arr.length; i++) loop, the two commands that execute in almost all iterations are i++ and i < arr . 在典型的for(var i = 0; i < arr.length; i++)循环中,几乎在所有迭代中执行的两个命令是i++i < arr This is arguably much faster than making a function call ( next() or yield() ). 可以说这比进行函数调用( next()yield() )快得多。

Moreover, the loop initiation ( var i = 0 ) is also faster than creating the iterator object with next() method or calling the generator to create the iterator. 此外,循环启动( var i = 0 )也比使用next()方法创建迭代器对象或调用生成器创建迭代器要快。 However, it highly depends on the implementation and the creators of Javascript engines do their best to accelerate such commonly used language features. 但是,它高度依赖于实现,并且Javascript引擎的创建者会尽最大努力来加速这种常用的语言功能。

I would say the difference is so marginal that I might want to spend my time optimizing other parts of the code. 我会说这种差异非常小,以至于我可能想花时间优化代码的其他部分。 The choice of syntax should consider code readability and maintainability more than performance, when the performance gain is so small for adding complexity. 语法的选择应该考虑代码的可读性和可维护性,而不是性能,这是因为性能增益太小而增加复杂性。 Having said that, use the syntax that makes more sense to you and other developers who maintain your code after you get rich and famous! 话虽如此,请使用对您和其他在您变得富有和出名之后维护代码的开发人员来说更有意义的语法! ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM