Array.map 的 Javascript 性能

2024-03-26

刚刚在 jsperf 中编写了一些测试用例来测试使用时命名函数和匿名函数之间的区别Array.map和其他替代方案。

http://jsperf.com/map-reduce-named-functions http://jsperf.com/map-reduce-named-functions

(请原谅网址名称,没有测试过Array.reduce在这里,我在完全决定要测试的内容之前命名了测试)

一个简单的 for/while 循环显然是最快的,但我仍然对慢 10 倍以上感到惊讶Array.map尽管...

然后我尝试了mozilla的polyfillhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Polyfill https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Polyfill

Array.prototype.map = function(fun /*, thisArg */)
{
    "use strict";

    if (this === void 0 || this === null)
        throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
        throw new TypeError();

    var res = new Array(len);
    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++)
    {
        // NOTE: Absolute correctness would demand Object.defineProperty
        //       be used.  But this method is fairly new, and failure is
        //       possible only if Object.prototype or Array.prototype
        //       has a property |i| (very unlikely), so use a less-correct
        //       but more portable alternative.
        if (i in t)
            res[i] = fun.call(thisArg, t[i], i, t);
    }

    return res;
};

然后我尝试了我自己编写的一个简单的实现......

Array.prototype.map3 = function(callback /*, thisArg */) {
    'use strict';
    if (typeof callback !== 'function') {
        throw new TypeError();
    }

    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;

    for (var i = 0, len = this.length; i < len; i++) {
        this[i] = callback.call(thisArg, this[i], i, this);
    };
};

结果摘要:

从最快到最慢:

  1. 对于简单/同时(大约相同)
  2. Map3(我自己的实现)
  3. Map2(Mozilla 填充)
  4. Array.map
  5. for in

观察结果

有趣的是,命名函数通常比使用匿名函数要快一些(大约 5%)。但我注意到,在 firefox 中使用命名函数时,polyfill 速度较慢,但​​在 chrome 中速度较快,但 chrome 自己的地图实现在使用命名函数时速度较慢...我每个测试了大约 10 倍,所以即使它不是严格的密集测试(jsperf已经这样做了),除非我的运气那么好,否则它应该足以作为指导方针。

另外,镀铬的map在我的机器上,该功能比 Firefox 慢 2 倍。根本没想到会这样。

还有... Firefox 自己的Array.map实现速度比 Mozilla Polyfill 慢...哈哈

我不确定为什么 ECMA-262 规范会这样规定map可用于数组以外的对象(http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.19 http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.19)。这使得整个映射函数慢了 3-4 倍(如我的测试所示),因为您需要在每个循环中检查属性是否存在......

结论

如果您考虑到不同浏览器的性能略有不同,那么命名函数和匿名函数之间并没有太大区别。

归根结底,我们不应该进行太多的微观优化,但我发现这很有趣:)


首先,这不是一个公平的比较。正如你所说,正确的 javascript 地图能够使用对象,而不仅仅是数组。所以你基本上是在比较两个完全不同的函数和不同的算法/结果/内部工作原理。

当然,正确的 javascript 映射速度较慢 - 它被设计为在更大的域上工作,而不是在数组上进行简单的操作。

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

Array.map 的 Javascript 性能 的相关文章

  • 使用画布元素作为文本区域

    我正在寻找有关如何使用类似于文本区域的画布元素的直接描述 我见过这样的项目Ace http ace ajax org 只是想知道如何像文本区域一样写入该区域 只是纯文本 没有什么花哨的 提前致谢 Ace 曾经是 Mozilla Skywri
  • jQuery - 提高处理 XML 时的选择器性能

    我正在处理一个 XML 文件 当使用 XPath 样式选择器选择节点时 该文件的性能非常慢 这是运行特别慢的部分代码 for i 0 i
  • 是否可以将自定义 HTML 添加到传单图层组和图层控件

    有什么方法可以将自定义 HTML 注入图层组和图层控件中吗 在我们的应用程序中 我们实现了滑块 输入 范围 来调整不透明度设置 并且很明显 在其控制容器内部的基础层上使用专用滑块是有意义的 没有选项或参数可以修改此控件 理想情况下 我们希望
  • Chrome 内存/垃圾收集问题

    我在使用 Chrome 时遇到内存 垃圾收集问题 我正在开发一个照片上传网站 该网站允许我的客户使用 HTML5 和文件 API 拖放照片进行上传 因此这在 IE 中不起作用 它仅适用于 Chrome 和 FF 我还没有在 Safari O
  • Twitter Bootstrap 轮播在加载时自动播放

    使用twitter bootstrap框架 如何调用轮播来 自动滑动 这意味着当页面加载时 轮播会自动滚动 我尝试过 javascript onLoad click 函数 a 下一个链接的 但这不起作用 你应该这样做Twitter Boot
  • SVG 中三角形的圆角

    我正在尝试制作一个具有圆角的三角形 三角形将如下所示 左下角是唯一看起来相当容易制作的角 主要是因为这是一个 90 度的 转弯 该转弯是使用QSVG 中的命令具有以下参数 Q x y height x y height RADIUS从我正在
  • 如何在 javascript 或 jquery 中按尺寸对图像进行排序

    如何在 JavaScript 或 jQuery 中按尺寸对图像进行排序 我的代码如下 var imgsrc if document images length lt 1 alert No images to open return for
  • Famo.us 滚动视图高度

    我正在尝试使用著名的顺序布局在滚动视图下方添加图像 但滚动视图的高度有问题 这就是我创建滚动视图的方式 var scrollview new Scrollview direction Utility Direction X options
  • AngularJS - 服务、工厂、过滤器等中的依赖注入

    因此 我想在我的 Angular 应用程序中使用一些插件和库 目前 我只是引用这些函数 方法 因为它们是在 99 的应用程序中以完全忽略依赖注入的方式使用的 我有 例如 javascript 库 MomentJS 它处理格式化和验证日期 并
  • 使用 Javascript eval() 100% 安全吗?

    我正在编写一个生成 Javascript 代码的 PHP 库 Javascript 代码有许多名为component001 component002 etc 页面通过 AJAX 动态加载 我需要通过 URL 变量传递组件的名称 然后由脚本进
  • Python——捕获异常的效率[重复]

    这个问题在这里已经有答案了 可能的重复 Python 常见问题解答 异常有多快 https stackoverflow com questions 8107695 python faq how fast are exceptions 我记得
  • 更改特定字符串的颜色

    有谁知道如果将特定单词输入文本区域 我如何更改它的颜色 例如 如果用户输入 你好我的朋友 它会动态地将 你好 更改为绿色 在google上花了很多时间 找不到任何相关的东西 谢谢 textareas 的设计目的不是选择性着色
  • 我可以在不使用 Jquery UI 的情况下获得 Jquery Pulsate Effect 吗?

    我遇到了由于某种原因无法使用 Jquery UI 的情况 我正在尝试在不使用 Jquery UI 的情况下获得 Jquery UI 脉冲效果 与此链接类似 http docs jquery com UI Effects Pulsate ht
  • javascript/jquery 禁用点击提交按钮,防止重复提交

    所以我的提交按钮如下所示 a href img src images user create product png border 0 a 当我双击它时 显然会双重提交 问题是 我将信息保存在数据库中 因此那里会有重复的信息 我不想那样 这
  • 简单的颜色变化

    我正在创建一个用户界面 用户可以在其中更改页面的颜色值 我想要的是获取分配给其背景颜色的值并将其变亮一定程度 我只是想获得一条亮点线 而不必每次都制作新图像 示例 用户将背景颜色设置为 ECECEC 现在我希望某个元素边框变成 F4F4F4
  • 获取 byte[]

    我有一个 html 画布 如下所示 output is a base64string of image data var oldImage new Image oldImage onload function var resizeRatio
  • window.open 使用 css 样式

    我想设计我的 window open 目前 我的网页上有一些项目由于解析了某个类而打开 然后在新窗口中打开指定的文本 我想更改字体大小 字体和填充等 这是我的 JavaScript 代码
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack
  • 指定在任何 Jest 设置发生之前运行的代码

    tl dr 是 1 我怎样才能让Jest使用原生的require函数可以在任何地方加载我的测试中的所有模块 2 我将在哪里 如何进行修改 即替换为esm加载程序 https github com standard things esm ht
  • 将 Angular Web 组件 EventEmitter 监听到 javascript

    我在以下工具的帮助下创建了一个小型网络组件本文 https medium com IMM9O web components with angular d0205c9db08f使用角度元素 其中包括 Input and Output 我能够将

随机推荐

  • Paintcode 和 Snap SVG

    我正在尝试桥接示例油漆代码 https www youtube com watch v 9SE2tmgYbCU and Snap SVG http snapsvg io docs Here http yepher com svgGearEx
  • Xamarin - 在 XAML 中将集合设置为自定义可绑定属性

    我有一个习惯ContentView具有定义的可绑定属性 public IEnumerable
  • SQL Server 2008 无法删除约束

    我正在尝试使用以下命令从表中删除主键约束 ALTER TABLE SchemaName LabourGrade DROP CONSTRAINT Labour Grade pk 并得到错误Labour Grade pk is not a co
  • Clojure/Scala 互操作?

    我正在尝试与这个简单的 scala 代码进行互操作 但遇到了一些麻烦 package indicators class DoubleRingBuffer val capacity Int 1000 var elements new Arra
  • 故事板的多个入口点

    我需要在启动时在 AppDelegate 中做出一系列决定 根据这些决定的结果 我需要转到故事板的特定部分 所以我的问题是 在不使用任何导航或选项卡控制器的情况下 我如何转到故事板的特定部分 OR 唯一受支持的选项是否具有多个故事板 对于每
  • 如何根据搜索到的字符串过滤列表框中的项目

    我有一个 Windows 窗体应用程序 C 其中包含一个列表框 我在其中添加了一些项目 我没有使用数据源 我想过滤 ListBox 中的项目以仅显示包含我正在搜索的字符串的项目 我通过保留原始项目的列表并在每次搜索字符串更改时从该列表中选择
  • 使用 URL::action() 时如何更改域

    我正在尝试复制 Laravel 3 中可用的内容 我希望能够为路由指定备用域名 例如 我有一条使用此代码生成以下内容的路线 URL action DashboardController something Produces http som
  • 无法转换“AppDelegate Proxy”类型的值

    我已经集成了 Localtyics iOS SDK 之后我收到如下错误 无法转换 LLAppDelegateProxy 类型的值 这意味着我无法获取应用程序委托对象的引用 我现在遇到麻烦了 因为我想要 Localytics 并且还想要 Ap
  • 批处理脚本在文件夹中查找空文件

    我需要识别文件夹中的零 KB 文件并将输出写入文本文件 下面是我使用批处理脚本找到的代码 我想根据我的以下要求进行自定义 echo off set out found txt for r c myfolderfilestosearch F
  • CS0234:System.Web 命名空间中不存在 Mvc

    我根据 Scott Hanselmen Phil Haack 和 Rob Conery 出版的 Professional ASP NET 3 5 MVC 第 13 章 将 ASP net 4 webform 项目转换为 Asp net MV
  • Angular JS:ng-click 范围集在 ng-if 中不起作用

    今天 我看到了 angularjs 中的一个错误 当您尝试直接在 ng click 中设置范围值时 当您的 ng click 位于测试相同范围值的 ng if 中时 它不起作用 gt http jsfiddle net 9j2TL 26 h
  • Android Management API - 使用密码退出 kiosk 模式

    我有问题 我有完全托管的设备并使用 Android Management API https developers google com android management https developers google com andr
  • Jquery 对象选择器作为字符串

    有没有办法获取 jquery 对象的选择器 例如 在 Firefox 中 我看到一个 jquery 对象为 p basket 但 jquery 中似乎没有办法获得这个选择器 有什么办法吗 Phil 如果 jQuery 对象是使用选择器字符串
  • 在 IL 中对空引用调用实例方法

    在 IL 中可以对空引用调用实例方法是否正确 有没有例子可以证明这一点 是的 这是可能的 只要该方法不使用this因为 CLR 不会对以下内容进行空检查call指示 You would have to modify the IL by ha
  • 如何检查我的应用程序是否在 android 中运行(不是作为服务)?

    Problem 我必须检查我的应用程序是否正在运行 当服务已经在后台运行时 基于它 我应该启动特定的活动或应用程序 我尝试或想出但失败的事情我尝试检查当前正在运行的进程 并根据它尝试确定应用程序是否正在运行 失败原因 获取应用程序运行状态一
  • 如何使用 CGImageRef 图像在 NSView 中显示图像

    我想在 NSview 或 NSImageView 中显示图像 在我的头文件中我有 interface FVView NSView NSImageView imageView end 这是我在实现文件中尝试做的事情 void drawRect
  • 将日期时间转换为时间戳并再次转换回来

    我在 Python 中的日期时间方面遇到了一些问题 我尝试将日期时间转换为时间戳 然后再转换回来 无论我如何尝试 最终结果都不一样 我总是以 datetime 2014 1 30 23 59 40 1998 的日期时间结束 import d
  • 使用 REST 是否必须使用适当的方法类型(POST、PUT、GET、DELETE)?

    我们在项目中使用 REST 调用 Web 服务来处理从用户界面进行的所有调用 目前 对于每个方法 签名都是以这种方式配置的 public class SaveNewAddressLabelService GET Consumes appli
  • XSLT 删除任意重复的同级元素

    答案here https stackoverflow com a 16715399 288341正在做我想要的事情 除了我不想只删除特定元素的重复同级元素 我想删除所有元素的重复同级元素 此外 出于我的目的 重复 元素将具有与其同级元素相同
  • Array.map 的 Javascript 性能

    刚刚在 jsperf 中编写了一些测试用例来测试使用时命名函数和匿名函数之间的区别Array map和其他替代方案 http jsperf com map reduce named functions http jsperf com map