删除js中数组的第一个元素的哪种方法可以提供更好的性能?

假设我们有这个数组:

let fruits = ['Apple', 'Orange', 'Banana', 'Lemon'];

1. shift approach

let a = fruits.shift();

2. splice approach

let [b] = fruits.splice(0, 1);

3. slice approach

let c;
[c, fruits] = [...fruits.slice(0, 1), fruits.slice(1)]

4. Destructuring approach

let d;
[d, ...fruits] = fruits;

请说明其中一种方法比另一种方法更快的原因.

我在jsbench.me&perf.link但我多次进行完全相同的测试,每次都得到180度相反的结果.

我知道不同的环境和引擎不同,所以我想知道在Chrome V8引擎中哪个更好.

推荐答案

根据我的经验,.shift()方法是最容易使用的.但是如果你想知道确切的代码速度,我用performance.now()个测试了每种方法.

大多数情况下,.shift()法是最快的.你可能会问为什么?好吧,它不会重新声明任何变量,因为其他变量是重新定义的.您只有on变量,它在调用shift()方法时自动返回.特别是最后两个例子是最慢的.他们重新定义了两个变量,一个变量被分配两次(c,d).一次,就跟let一起,另一次是在申报的时候.

这是我用于测试的代码,请随意编辑.

    function speedTest(times) {
    let shiftAvg = 0;
    let spliceAvg = 0;
    let sliceAvg = 0;
    let destructuringAvg = 0;
    let t0, t1;
    let fruits = Array(10000).fill('test');
    for (var i = 0; i < times; i++) {

        t0 = performance.now();
    
        let a = fruits.shift();
    
        t1 = performance.now();

        shiftAvg += t1 - t0;
    
        resetFruits();
        
        t0 = performance.now();
    
        let [b] = fruits.splice(0, 1);
    
        t1 = performance.now();
        spliceAvg += t1 - t0;
    
        resetFruits();
        
        t0 = performance.now();
    
        let c;
        [c, fruits] = [...fruits.slice(0, 1), fruits.slice(1)];
    
        t1 = performance.now();
        sliceAvg += t1 - t0;
    
        resetFruits();
        
        t0 = performance.now();
    
        let d;
        [d, ...fruits] = fruits;
    
        t1 = performance.now();
        destructuringAvg += t1 - t0;
    
        resetFruits();
    }
    
    shiftAvg = shiftAvg / times;
    spliceAvg = spliceAvg / times;
    sliceAvg = sliceAvg / times;
    destructuringAvg = destructuringAvg / times;

    return [
        {"avg": destructuringAvg, "approach": 'destructuring'},
        {"avg": spliceAvg, "approach": 'splice'},
        {"avg": sliceAvg, "approach": 'slice'},
        {"avg": shiftAvg, "approach": 'shift'}
    ];
    
    function resetFruits() {
        fruits = Array(10000).fill('test');
    }
}

let result = speedTest(20000).sort((a, b) => (a.avg > b.avg) ? 1 : -1);

result.map((item, index, self) => {
    if(index === 0) {
        console.log(index + 1, item.approach, item.avg, `fastest`);
    }
    else {
        console.log(index + 1, item.approach, item.avg, `${parseInt(item.avg / self[0].avg * 100 - 100)}% slower`);
    }
    
});

此外,不仅代码执行速度快,而且键入array.例如,slice()比键入整个解构代码更快.

我希望我能帮助你:)

Javascript相关问答推荐

在JavaScript中对大型级联数组进行切片的最有效方法?

materialized - activeIndex返回-1

我试图实现用户验证的reduxstore 和操作中出了什么问题?

传递一个大对象以在Express布局中呈现

Msgraph用户邀请自定义邮箱模板

Regex结果包含额外的match/group,只带一个返回

如何从网站www.example.com获取表与Cheerio谷歌应用程序脚本

我的角模板订阅后不刷新'

为什么我的getAsFile()方法返回空?

React.Development.js和未捕获的ReferenceError:未定义useState

TypeError:无法分解';React2.useContext(...)';的属性';basename';,因为它为空

使用js构造一个html<;ath&>元素并不能使其正确呈现

如何为仅有数据可用的点显示X轴标签?

OnClick更改Json数组JSX中的图像源

Next.js无法从外部本地主机获取图像

在ChartJS中使用spanGaps时,是否获取空值的坐标?

我们是否可以在reactjs中创建多个同名的路由

如何在Reaction中设置缺省值, Select 下拉列表,动态追加剩余值?

使用props 将VUE 3组件导入JS文件

通过ng-绑定-html使用插入的HTML中的函数