lodash.each가 native forEach보다 빠른 이유는 무엇입니까?
자체 범위로 for 루프를 실행하는 가장 빠른 방법을 찾으려고했습니다. 내가 비교 한 세 가지 방법은 다음과 같습니다.
var a = "t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t".split();
// lodash .each -> 1,294,971 ops/sec
lodash.each(a, function(item) { cb(item); });
// native .forEach -> 398,167 ops/sec
a.forEach(function(item) { cb(item); });
// native for -> 1,140,382 ops/sec
var lambda = function(item) { cb(item); };
for (var ix = 0, len = a.length; ix < len; ix++) {
lambda(a[ix]);
}
이것은 OS X의 Chrome 29에 있습니다. 여기에서 직접 테스트를 실행할 수 있습니다.
lodash는 어떻게 .each
네이티브보다 거의 두 배 빠른 .forEach
가요? 게다가 평야보다 어떻게 빠른 for
가요? 마법? 마법?
_.each()
와 완전히 호환되지 않습니다 [].forEach()
. 다음 예를 참조하십시오.
var a = ['a0'];
a[3] = 'a3';
_.each(a, console.log); // runs 4 times
a.forEach(console.log); // runs twice -- that's just how [].forEach() is specified
따라서 lodash의 구현 if (... in ...)
에는 성능 차이를 설명 할 수 있는 검사 가 누락되었습니다 .
위의 주석에서 언급했듯이 네이티브와의 차이점 for
은 주로 테스트의 추가 함수 조회로 인해 발생합니다. 보다 정확한 결과를 얻으려면이 버전을 사용하십시오.
for (var ix = 0, len = a.length; ix < len; ix++) {
cb(a[ix]);
}
http://jsperf.com/lo-dash-each-vs-native-foreach/15
http://kitcambridge.be/blog/say-hello-to-lo-dash/
lo-dash 개발자는 네이티브의 상대적 속도가 forEach
브라우저마다 다르다고 설명합니다 (여기와 비디오에서) . 그냥 때문에 forEach
더 빨리로 만든 간단한 루프보다 것을 의미하지 않는다 네이티브 for
또는 while
. 우선 forEach
더 특별한 경우를 처리해야합니다. 둘째, forEach
함수 호출 등의 (잠재적) 오버 헤드와 함께 콜백을 사용합니다.
chrome
특히 (적어도 lo-dash 개발자에게는) 상대적으로 느린 forEach
. 따라서 해당 브라우저의 경우 lo-dash는 자체의 간단한 while
루프를 사용하여 속도를 얻습니다. 따라서 속도 이점이 있습니다 (그러나 다른 사람들은 그렇지 않습니다).
Lo-Dash는 네이티브 메서드를 현명하게 선택하여 (주어진 환경에서 빠른 것으로 알려진 경우에만 네이티브 구현을 사용하여) 네이티브와 관련된 성능 비용 및 일관성 문제를 방지합니다.
예, lodash / underscore는 각각 .forEach
. 엔진이 게터없이 희소 배열을 빠르게 확인할 수 없다면 함수를 정말 느리게 만드는 미묘한 세부 사항이 있습니다.
이는 99 % 사양을 준수하며 일반적인 경우에 대해 V8 에서 각각 lodash와 동일한 속도로 실행됩니다 .
function FastAlmostSpecForEach( fn, ctx ) {
"use strict";
if( arguments.length > 1 ) return slowCaseForEach();
if( typeof this !== "object" ) return slowCaseForEach();
if( this === null ) throw new Error("this is null or not defined");
if( typeof fn !== "function" ) throw new Error("is not a function");
var len = this.length;
if( ( len >>> 0 ) !== len ) return slowCaseForEach();
for( var i = 0; i < len; ++i ) {
var item = this[i];
//Semantics are not exactly the same,
//Fully spec compliant will not invoke getters
//but this will.. however that is an insane edge case
if( item === void 0 && !(i in this) ) {
continue;
}
fn( item, i, this );
}
}
Array.prototype.fastSpecForEach = FastAlmostSpecForEach;
undefined를 먼저 확인하면 루프의 일반 배열을 전혀 처벌하지 않습니다. 엔진은 내부를 사용하여 이상한 배열을 감지 할 수 있지만 V8은 그렇지 않습니다.
Here's an updated link (circa 2015) showing the performance difference which compares all three, for(...)
, Array.forEach
and _.each
: https://jsperf.com/native-vs-underscore-vs-lodash
Note: Put here since I didn't have enough points yet to comment on the accepted answer.
참고URL : https://stackoverflow.com/questions/18881487/why-is-lodash-each-faster-than-native-foreach
'Program Tip' 카테고리의 다른 글
최적의 scrypt 작업 요소는 무엇입니까? (0) | 2020.11.17 |
---|---|
stdout을 변수로 캡처하지만 여전히 콘솔에 표시 (0) | 2020.11.17 |
목록 이해 필터링-“set () 트랩” (0) | 2020.11.17 |
AttributeError : '모듈'개체에 '요청'속성이 없습니다. (0) | 2020.11.17 |
브라우저 간 방식으로 뷰포트의 정확한 높이와 너비를 찾습니다 (Prototype / jQuery 없음). (0) | 2020.11.17 |