- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的印象是大多数 ES6 特性只是语法糖。但是,当我比较 MDN 上的 find polyfill 时使用常规的 ES6 实现,它似乎快了一半。究竟是什么解释了这种性能差异,难道在引擎盖下不都是一样的吗?
请引用下面的代码片段以获取基准:
// Find polyfill
function find(obj, predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(obj);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;
}
const testArray = ["Hello", "Hi", "Good Morning", "Good Afternoon", "Good Evening", "Good Night"];
// Polyfill benchmark
console.time('findPolyfill');
for (var i = 0; i < 10000; i++) {
find(testArray, (item) => item === "Hello")
}
console.timeEnd('findPolyfill');
// ES6 benchmark
console.time('find ES6');
for (var i = 0; i < 10000; i++) {
testArray.find((item) => item === "Hello");
}
console.timeEnd('find ES6');
最佳答案
native 版本可以利用内部优化和快捷方式,只要它们不能从外部观察到。如果不是编译的机器代码,它也可能被预先优化并至少存储为字节码。 (取决于 JavaScript 引擎。)
相比之下,polyfill 是对规范所说的内容的非常迂腐的呈现,除非你在一个紧密的循环中运行它超过 5-10k 次左右,否则不太可能被选择用于积极优化引擎。
有趣的是,您的循环设置为运行 10k 次,因此很可能就在引擎对其进行优化之前停止。或者引擎可能会在中途优化它——进一步延迟结果。例如,对我来说,下面的 polyfill 第一次运行时间约为 6 毫秒,但第二次和第三次运行时间约为 1.1 毫秒(Chrome v73 中的 V8 v7.3)。所以很明显它在第一次运行时得到了优化(反常地,这可能会减慢运行速度,但显然会加快后续运行速度)。
// Find polyfill
function find(obj, predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(obj);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;
}
const testArray = ["Hello", "Hi", "Good Morning", "Good Afternoon", "Good Evening", "Good Night"];
function testPolyfill() {
// Polyfill benchmark
console.time('findPolyfill');
for (var i = 0; i < 10000; i++) {
find(testArray, (item) => item === "Hello")
}
console.timeEnd('findPolyfill');
}
function testNative() {
// ES6 benchmark
console.time('find ES6');
for (var i = 0; i < 10000; i++) {
testArray.find((item) => item === "Hello");
}
console.timeEnd('find ES6');
}
testPolyfill();
testNative();
testPolyfill();
testNative();
testPolyfill();
testNative();
关于javascript - 为什么 Array.prototype.find() polyfill 比 ES6 实现慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55534013/
https://github.com/Yaffle/EventSource 我使用上面的是因为我想获得在 IE11 中工作的 promise ,我已经用 npm 安装了它但不确定我应该如何实现它。我在
有没有办法“摇树”babel-polyfill,这样只有我使用的功能是 polyfill? 也就是说,如果我从不在我的代码中使用 String.padStart,则不应包含它的 polyfill。 最
在我的入口点中使用 babel 转换将 babel-polyfill 导入到 Browserify 后,IE11 仍然提示 Object.assign。除了 Object.assign 之外,我的项目
这里是 Polyfill 新手。我对这个简单的例子完全感到困惑,在这个例子中我想初始化一个类型化数组: var x = new Uint8Array(3).fill(42); console.log(
我正在使用 ChildNode.remove()并且我由 Mozilla 描述我需要一个用于 IE 的 polyfill。我正在使用配置了 babel-polyfill 的 webpack: "ba
我正在使用 nuxt vuetify 模板构建一个静态站点,虽然它很棒并且提供了很多已经为我完成的配置和设置,但我发现很难让我的站点在 Internet Explorer (11) 上顺利运行。 由于
使用 core-js 填充的函数(例如,babel-polyfill)显示为原生。 Promise.race.toString() 产生: function race() { [native
我有以下实用程序: // Utility function to remove base64 URL prefix and store base64-encoded string in
我得到的错误 Error: Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has b
我正在学习基于 React 的 Udemy 类(class)(这是 Brad Schiff 为我们其他人准备的 React 类(class) here),我收到一个与 webpack 相关的错误,导致
我将 Ionic 3 项目升级为 Ionic 4 项目。使用“ionic serve”启动服务器时,我总是会收到上述错误。 我试过很多东西,例如: 在 polyfills.ts 文件中, (windo
我知道每个已知的浏览器都支持“decodeURIComponent”,但我试图通过 polyfill 来更好地理解它。 Atob、Btoa 有很多 polyfill……但出于某种原因,我没有找到任何用
我无法理解为什么检查对应于行 if (i in t) - 第 18 行放在 filter function polyfill 中: if (!Array.prototype.filter) { A
我正在尝试为传播运算符创建一个 polyfill。我的目标是创建类似于扩展运算符的东西,我可以使用三重 @@@ 符号代替三重点。 例如,在 ES6 中 function sum(x, y, z) {
This article启发我将我为 React 应用程序加载的 polyfill 外部化,并且只为需要它们的浏览器加载它们。一个简单的测试: function browserSupportsAllF
我创建了一个自托管 ServiceStack 服务,该服务基于其 showcase chat application 在 Windows 服务中运行。 。 但是,我没有进一步讨论的是尝试将客户端编写为
我正在开始一个新项目,目标是 MSVC、GCC(最新)、GCC 4.3 ARM 等等。我们构建的 waf 构建系统具有编译器的 C++11 功能检测。 我现在为 C++11 目标编译器中的所有功能提供
我正在寻找一种工具,它可以让我利用 native HTML5 拖放功能,并填充对过去浏览器的支持。 有这样的东西吗? Modernizr 的页面 (https://github.com/Moderni
是否有一个 polyfill 来处理 Safari 4 (iOS) 和 IE 中的 CSS 背景大小调整 最佳答案 可以试试这个。 http://nooshu.com/jquery-plug-in-s
我正在构建一个我的目标群体非常普遍的网站(13 岁到 oo,所以你好 IE9,你好古老的 android 浏览器),所以我需要 polyfills 来处理一些东西(viewport,calc 等)。在
我是一名优秀的程序员,十分优秀!