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

2024-03-29

下面的代码是源码negateLodash 中的函数。我们可以看到,当参数长度小于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);
  };
}

抱歉,我的水晶球还在修复中。所以我只能给你我对作者意图的最好猜测。

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

基本上优化了整个结构,甚至内联了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()。很少想到它,但这是一个将被其他库使用的库,因此每个性能问题都可能呈指数级增长。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 lodash 在否定函数中使用 switch-case? [复制] 的相关文章

随机推荐

  • 将 getFragmentManager() 与 actionbarsherlock 库一起使用时出现 java.lang.NoSuchMethodError

    我自己的项目使用
  • Python 中索引的其他形式

    我正在学习机器学习课程 在对 numpy 库的回顾中 使用了一种我以前从未见过的索引方法 我们定义a np array 1 2 3 4 5 6 随后创建两个新数组 np array a 0 0 a 1 1 a 2 1 这是我所知道的索引方式
  • D3 气泡图“bubble.nodes 不是函数”

    我正在关注 Mike Bostock 的教程here https bl ocks org mbostock 4063269创建气泡图 除了我使用自己的数据集并且使用 d3 v4 我对 d3 很陌生 我知道 v4 与 v3 相比发生了很多变化
  • 为什么这个异常没有被捕获?

    我正在尝试运行以下代码 class Program static void Main string args var task Task Factory StartNew gt throw new ApplicationException
  • 使用Systemjs时检测页面上是否加载了Angular

    UPDATE 这个问题专门讲了角2 现在是过时的 在发布时 没有办法检测它是否已加载到页面上 我还没有测试过其他版本 但是 Angular 8 现在有一种简单的方法来检测这一点 并且已经在下面的答案中指出了 我正在尝试找出一种好的 最好是最
  • 用于获取访问次数最少的目录日期/时间的 shell 命令

    find 命令中是否有可用的排序选项来获取访问日期 时间最少的目录 find type d printf A p n sort n tail n 1 cut d f 2 如果您喜欢不带前导路径的文件名 请替换 p by f
  • 如何在Picasso中清除缓存并重新加载图像?

    我在用Picasso在我的应用程序中加载图像 但我面临一个问题 我的图像URL是相同的 但图像正在改变backend调用相同的 URL 但是Picasso加载保存在缓存中的相同图像 现在我想清除该图像的缓存并再次重新加载图像 我尝试过的我搜
  • 在 Windows 10 上使用 mingw 进行 CMake:检测 CXX 编译器 ABI 信息 - 失败

    我想使用 cmake 在 Windows 10 上创建 MinGW Makefile 我已经安装了 mingw 并且可以毫无问题地使用 mingw32 make 和 g 命令 测试项目是一个超级简单的CMakeLists txt文件 cma
  • 版本控制压缩文件(docx、odt)

    有些格式实际上是伪装的 zip 文件 例如docx 或 odt 如果我将它们直接存储在版本控制中 它们将被作为二进制文件处理 我理想的解决方案是 有一个钩子可以创建一个foo docx 每个目录foo docx提交之前的文件 将所有文件解压
  • C中的多态性

    我正在用 C 语言设计一个程序来操作几何图形 如果每种类型的图形都可以由相同的基元操作 那将非常方便 我怎样才能在C中做到这一点 通常使用函数指针来完成此操作 换句话说 保存数据的简单结构and指向操作该数据的函数的指针 在 Bjarne
  • 恢复 Typescript 定义 Nuget 包

    我目前正在开发一个新项目 该项目将 Typescript 用于所有客户端代码 我使用许多纯 JavaScript 库来让它们与我的 Typescript 一起使用 我使用 Nuget 通过以下包管理器命令提取 d ts 文件 包管理器命令示
  • UserManager SendEmailAsync 未发送电子邮件

    我正在使用以下代码尝试异步发送电子邮件 但没有发送电子邮件 并且我不确定哪里做错了 我还在 web config 中添加了电子邮件协议的第二段代码 发送电子邮件异步代码 await UserManager SendEmailAsync us
  • Android 上的 AWS CloudWatch Log

    我正在尝试在 Android 应用程序中使用 AWS CloudWatch Log 我对 aws client 有以下配置 val basicAWSCredentials BasicAWSCredentials Xxxxxx Yyyyyy
  • 字符串交错的动态规划问题解决方案

    我试图解决这个问题 但我放弃了 找到了下面的解决方案 尽管我不明白该解决方案是如何工作的 或者为什么它有效 任何深入的解决方案将不胜感激 问题 Given s1 s2 s3 求是否s3由交错形成s1 and s2 例如 给定 s1 aabc
  • 如何从 python 中的命名元组中获取名称?

    我创建一个像这样的命名元组 from collections import namedtuple spam namedtuple eggs x y z ham spam 1 2 3 然后我可以使用例如访问火腿的元素 gt gt gt ham
  • 禁用部分内容的 CSS

    我正在使用 Yii bootstrap 扩展 但遇到一些样式问题 因为 bootstrap css 文件影响页面的主要内容 我的主要内容是使用 OpenLayers 完成的地图 因此我在它们之间混合样式时遇到了一些问题 我尝试做一个更通用的
  • 没有 v-model 的 Vue.JS 复选框

    尝试在不使用 v model 的情况下创建复选框
  • 服务层/存储库模式

    我正在使用 EF4 的服务层 存储库 工作单元模式构建一个 MVC 应用程序 我对逻辑有点困惑 我知道重点是解耦系统 但我有点困惑 因此 MVC 控制器调用服务来填充视图模型 那么可以肯定地说 MVC 应用程序耦合到服务层吗 然后服务层调用
  • sqlite3 - 插入 - javascript 对象作为值

    使用 javascript 对象作为 sqlite3 插入的值的最简单的解决方案是什么 下面的代码不起作用 const values name John age 34 language english db run INSERT INTO
  • 为什么 lodash 在否定函数中使用 switch-case? [复制]

    这个问题在这里已经有答案了 下面的代码是源码negateLodash 中的函数 我们可以看到 当参数长度小于4时 它使用switch case而不是使用apply直接地 这段代码有什么魔力呢 它会使性能更好吗 为什么分割点是4 functi