- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
原生 Array.prototype.forEach()
非常慢。我不知道为什么。另外,我不知道为什么在Underscore.js中实现的 _.each()
。我认为人们通常认为,如果它在库中,或者它是由浏览器实现的,那么它是正确的/有效的,直到被证明不正确/有效。
证明如下:
http://jsperf.com/native-vs-implmented-0
如果我们简单地从 underscore, _.each 中删除 native 调用,我们得到:
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
我也打算询问下划线团队,但我想确认我没有遗漏任何明显的东西。
这是可以提高性能的有效缩减吗?性能下降是希望有一天它会更快吗?这种减少是否可以在不丢失有用功能的情况下提高性能?
最佳答案
看看Lo-Dash .作者做了很多工作来研究这些性能问题,尤其是在 this blog post 中。和 this video .
如果性能是您的目标,那么您最好编写自己的迭代器,该迭代器只执行您需要的操作,而不会执行其他操作——那么它的性能应该会非常好。例如,在许多情况下,您只需要数组元素而不需要索引。您绝对不需要使用 .call()
将数组元素作为 this
传递给回调,因为它也是作为命名参数传递的。你真的需要让 return false;
在回调中终止循环吗?我不记得我最后一次用它了。所以它可以像这样简单:
function eachElement( array, callback ) {
for( var i = 0, n = array.length; i < n; ++i ) {
callback( array[i] );
}
}
在速度方面很难超越它。
当你需要索引时,你可以有一个单独的版本:
function eachElementAndIndex( array, callback ) {
for( var i = 0, n = array.length; i < n; ++i ) {
callback( array[i], i );
}
}
你可以使用更短的函数名;为了清楚起见,我只是在这里使用了这些长名称。结果可能是 eachElementAndIndex()
足够快,因此您可以调用它 each()
并完成它。
值得注意的是,@YuryTarabanko在上面的评论中指出,这些简化的迭代器不符合 Array.prototype.forEach()
的规范。除了不将数组元素作为 this
传递并且不将整个数组作为第三个参数传递之外,它们不检查丢失的元素并将为 0 中的每个数组索引调用回调
到 array.length - 1
而不管数组元素是否实际存在。例如。
其实Underscore.js的_.each()
在这方面是不一致的。当它回退到 Array.prototype.forEach()
时,它会跳过缺失的元素,但当它使用自己的 for
循环时,它会包含它们。
尝试转到 underscorejs.org并将其粘贴到 Chrome 控制台中:
function eachElementAndIndex( array, callback ) {
for( var i = 0, n = array.length; i < n; ++i ) {
callback( array[i], i );
}
}
function log( e, i ) {
console.log( i + ':', e );
}
var array = [];
array[2] = 'two';
console.log( 'eachElementAndIndex():' );
eachElementAndIndex( array, log );
console.log( '_.each() using native .forEach():' );
_.each( array, log );
console.log( '_.each() using its own loop:' );
var saveForEach = Array.prototype.forEach;
delete Array.prototype.forEach;
_.each( array, log );
Array.prototype.forEach = saveForEach;
console.log( 'Done' );
它记录:
eachElementAndIndex():
0: undefined
1: undefined
2: two
_.each() using native .forEach():
2: two
_.each() using its own loop:
0: undefined
1: undefined
2: two
Done
在许多(可能是大多数)情况下,缺少元素并不重要。您正在使用您创建的数组或 JSON 数组,并且您知道它没有任何缺失的元素。特别是对于 JSON 数组,这从来都不是问题,因为 JSON 没有办法生成缺少元素的数组。 JSON 数组可以有 null
元素,但 `.forEach() 像其他任何元素一样包含这些元素。
只要您的简化迭代器执行您想要的操作并且未命名为 Array.prototype.forEach
,您就不必担心它会满足您自己以外的任何规范。但是,如果您确实需要跳过丢失的数组元素,请在您自己的代码中考虑到这一点或使用标准的 .forEach()
。
此外,为了进一步简化您正在查看的 Underscore 代码,因为我们正在谈论 .forEach()
,这意味着我们只在谈论
部分,而不是 _.each()
的 ArrayObject
部分。所以真正感兴趣的代码路径是这样的:
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
}
};
关于javascript - 如何简化和加速_.each?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17457171/
过去几天我一直试图解决这个问题,但我做不到。我正在尝试生成 _ _ _ 形式的随机数。 _ _ _ _ 小数点前 3 位,然后是 4 位小数。 非常感谢任何帮助。谢谢, 院长 最佳答案 您发布的代码有
我的方法有问题。我需要从主类调用的方法的输出打印我: 需要这个输出:_ _ _ _ _ 我知道我可以将 System 的静态方法放入循环中,但这不是我想要的解决方案。我需要它来打印主类中方法的输出。
我正在学习 Scala,有一个非常基本的问题。考虑以下两个使用占位符语法的表达式 - // Syntax A val fnA = (_: Int, _: Int) => _ / _ // Synta
我正在使用图书馆 URLEmbeddedView 它在其库中定义了以下代码: func addConstraints(with view: UIView, center: CGPoint, multi
我一直在许多受人尊敬的文档中看到这个相当令人尴尬的事情:_|_ 或 (_|_) 找不到它的定义(Google 不能很好地处理符号)。那到底是什么呢? 最佳答案 来自 here :- Bottom Th
,_,( ){ ,_,| ,_,&};,_, 不知道是什么意思... 看起来像一个 bash 命令,但它可能是 s bash shell 指令或其他东西如果有人可以帮助理解这一点,我们将不胜感激。当我
所以我正在尝试构建一个函数,它接受一个元组列表并找到具有最大第二个元素的元组。但是我遇到了模式匹配错误。 这是我的代码。 resultTuple :: [((Int,Int),Int)] ->
我在 try Flow 编辑器中重现了我的情况,可以访问 here . 以下是链接发生问题时的代码: /* @flow */ type PayloadType = 1 | 2 | 3; type Tr
我在plfa读到这样一段代码。 import Relation.Binary.PropositionalEquality as Eq open Eq using (_≡_; refl; cong; s
这个问题在这里已经有了答案: Swift 3.0: compiler error when calling global func min(T,T) in Array or Dictionary e
是否有理由使用一个而不是另一个?似乎 _.some 和 _.map 更易于使用或适用于更多情况(根据我非常有限的经验),但从阅读它来看,它们听起来好像应该做同样的事情。我敢肯定还有其他这样的例子,我很
在 Xcode 7 Beta 中开始使用 Swift 2 后,出现错误 cannot invoke。是什么导致了这个问题? 我试图通过以下两个问题找出我的问题,但我仍然收到错误:Question 1
所以我玩了一会儿,试图写一些关于存在和变化的东西,我遇到了这段有趣的代码。 final case class Box[+T](val value: T) { def >>=[U](f: T =>
Here is the screenshot for the error. 遵循本教程 https://developers.google.com/places/ios-api/start 在本教程中
我正在为许多标准的 Underscore.js 函数重写底层代码,以提高我的 JavaScript 技能,但我有点受困于 _.every/ _.全部。似乎在库本身中,_.every/_.all 函数仅
我在 shell 脚本中多次看到他们在 if 比较中使用 "_",如下所示: if [ "_$str" = "_" ]; then ....; fi 上面的代码通过比较 if [ "_$str"= "
我正在尝试快速过滤字典: var data: [String: String] = [:] data = data.filter { $0.1 == "Test" } 上面的过滤器代码在 Swift
我在 Entity Framework 核心映射方面遇到了问题。我收到此异常“不支持从‘付款’到‘购买。付款’的关系,因为拥有的实体类型‘购买’不能位于非所有权关系的主要方面。”在调试此功能的测试时。
我正在尝试模拟groovy.sql.Sql调用(查询,params [],闭包)类。 下面是我正在尝试在DatabaseService类文件中的方法。 public void getUsers(Lis
在阅读 dart 代码时,我经常看到一些仅使用下划线 _ 参数调用的函数。这让我困扰了一段时间,由于 flutter 改进了它的分析消息,我有了一些线索......但我觉得我并没有真正理解这个概念:-
我是一名优秀的程序员,十分优秀!