2017-12-07 9 views
2

다음 코드는 lodash의 negate 함수의 소스 코드입니다. 우리가 볼 수 있듯이 매개 변수의 길이가 4보다 작 으면 apply 대신에 switch-case을 직접 사용합니다. 이 코드에 대한 어떤 마법? 성능이 향상 되었습니까? 그리고 분리 점이 4 인 이유는 무엇입니까?lodash가 negate 함수에서 switch-case를 사용하는 이유는 무엇입니까?

function negate(predicate) { 
    if (typeof predicate != 'function') { 
    throw new TypeError(FUNC_ERROR_TEXT); 
    } 
    return function() { 
    var args = arguments; 
    switch (args.length) { 
     case 0: return !predicate.call(this); 
     case 1: return !predicate.call(this, args[0]); 
     case 2: return !predicate.call(this, args[0], args[1]); 
     case 3: return !predicate.call(this, args[0], args[1], args[2]); 
    } 
    return !predicate.apply(this, args); 
    }; 
} 
+0

잘 모르겠지만 'switch'가'if..else' 래더보다 잘 수행된다고 생각합니다. 또한 타이핑도 적습니다. – Rajesh

+2

OP의 질문은'if..else' 대신'switch'를 사용하는 이유가 아닙니다. 문제는 조건부가있는 이유입니다. – JanS

+0

스플릿 포인트는 4입니다. 왜냐하면 당신은 자신이 반복하지 않는 한, oop에서 3 개 이상의 매개 변수를 사용하는 함수가 없어야합니다. (또한 손으로 더 많은 경우를 하드 코딩하는 것은 상당히 고통스럽고 지루합니다) . 그리고 그들은 아마도 벤치 마크를했을 것입니다.'apply'는 아마도'call' 메소드보다 느릴 것입니다. –

답변

0

Sry,하지만 수정 구슬이 아직 수리 중입니다. 그래서 나는 저자의 의도에 대해 가장 잘 추측 할 수 있습니다.

여기에 요점은 switch에 관한 것이 아니라 오히려 최적화 프로그램이이 전체 구문을 이러한 경로 중 하나에 변환 할 수 있도록하는 것이라고 생각합니다. 함수가 일관된 인수 집합으로 호출된다고 가정 할 때.

기본적으로이 전체를 constuct away로 최적화하고 predicate의 함수 본문을이 의사 코드와 같은 것으로 인라이닝합니다. 기능을 가정
는 항상 2 개 인자

function(){ 
    //a gate to ensure the optimization is still correct/applicable 
    //probably more complex than this 
    if(arguments.length === 2){   
     //assign predicate function args 
     var value = arguments[0], index = arguments[1]; 
     [function body of predicate] 
    }else{ 
     [de-optimize] 
     //execute the de-optimized version of this function 
    } 
} 

왜 0..3 인수를 불렀다? 이런, 가장 일반적인 경우입니다. 그리고 기본 경우는 완전성을 위해서만 존재하며 (결코 다시는 제 의견) 절대로 안타깝습니다.

다른 점은 Function#call()이 내 경험으로는 Function#apply()보다 약간 빠르다는 것입니다. 거의 생각조차 할 수 없지만 다른 라이브러리에서 사용할 라이브러리이므로 모든 성능 문제가 기하 급수적으로 증가 할 수 있습니다.