为什么lodash在否定函数中使用switch-case?

时间:2017-12-07 10:33:56

标签: javascript lodash

以下代码是lodash中negate函数的源代码。我们可以看到,当参数长度小于4时,它使用switch-case而不是直接使用apply。这段代码有什么神奇之处?它会使性能更好吗?为什么分裂点是4?

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);
  };
}

1 个答案:

答案 0 :(得分:0)

Sry,但我的水晶球还在修理中。因此,我只能对作者的意图给出最好的猜测。

我认为这里的重点不是switch,而是让优化器将整个构造转换为这些路径中的一个,假设该函数将使用一组一致的参数进行调用。 / p>

基本上优化了整个构造,甚至将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参数? imo,这些是最常见的情况。而默认情况只是为了完整性而且(再次,我的意见)应该永远/很少被击中。

另一点可能是Function#call()在我的经历中比Function#apply()快一点。很少考虑它,但这是一个将被其他库使用的库,因此每个性能问题都可能会有所增加。