JS几种变量交换方式以及性能分析对比

 

原文

原文是自己博客上发布的
JS几种变量交换方式以及性能分析对比

前言

“两个变量之间的值得交换”,这是一个经典的话题,现在也有了很多的成熟解决方案,本文主要是列举几种常用的方案,进行大量计算并分析对比。

起由

最近做某个项目时,其中有一个需求是交换数组中的两个元素。当时使用的方法是:

arr = [item0,item1,...,itemN];
//最初使用这段代码来交换第0个和第K(k<N)个元素
arr[0] = arr.splice(k, 1, arr[0])[0];

当时觉得这种方法很优雅,高逼格。。。

后来,业余时间又拿这个研究下了,顺带自己写了个分析工具,和普通方式进行对比。

结果,大大的出乎我的意料,这种方式的效率比我想象的要低的多。以下是其中一个测试结果的图

于是,基于这点,又研究了下其它的几种数值交换的方式,一起整合进入了分析工具中,才有了本文的这次总结。

JS变量交换的几种方式

其实关于JS的变量交换,使用最广泛的几种方式基本已经是前端人员必备的技能了,本文正好借此分析研究的契机,列举了本次分析中用到的几种交换方式:

第一种:普通临时变量交换方式

适用性: 适用于所有类型
代码如下:

tmp = a;
a = b;
b = tmp;

简要说明:
这是用到的最广泛的一种方式,经实战测试分析,性能也很高

(在JS中,这种方式效率确实很高,而且就算是其它语言中,只要tmp变量提前创建,性能也不会很低,反而是一些杂技派和少数派性能方面很低)

基本上可以说: 经典的才是最优雅的

第二种:利用一个新的对象来进行数据交换

适用性: 适用于所有类型
代码如下:

a = {a : b, b : a};
b = a.b
;a = a.a;

简要说明:
这种方式在实战中应用的很少

第三种:利用一个新的数组来进行数据交换

适用性: 适用于所有类型
代码如下:

a = [b, b=a][0];

简要说明:
这种方式在各大论坛中都有看到有人使用,但经测试实际性能并不高

第四种:利用数组交换变量(需EJS支持)

适用性: 适用于所有类型
代码如下:

`[a, b] = [b, a];

简要说明:
这也是在ES6出来后看到有人用的,实际在现有的浏览器中测试,性能很低

第五种:利用try catch交换

适用性: 适用于所有类型
代码如下:

a=(function(){;
try{return b}
finally{b=a}}
)();

简要说明:
这种方法应该是基本没人使用的,也没有什么实用性,而且性能也是属于在各种方法中垫底的

第六种:异或操作交换变量第一种方式

适用性: 适用于数字或字符串
代码如下:

a = (b = (a ^= b) ^ b) ^ a;

简要说明:
异或方法在数字或字符串时用到的比较普遍,而且性能也不低

第七种:异或操作交换变量第二种方式

适用性: 适用于数字或字符串
代码如下:

a ^=b;
b ^=a;
a ^=b;

简要说明:
异或方法在数字或字符串时用到的比较普遍,而且性能也不低

第八种:数字之间的加减运算来实现,第一种加减方式

适用性: 仅适用于数字
代码如下:

a = a + b;
b = a - b;
a = a - b;

简要说明:
这种用法在只用于数字间的交换时,性能也不弱

第九种:数字之间的加减运算来实现,第一种加减方式

适用性: 仅适用于数字
代码如下:

a = b -a +(b = a);

简要说明:
这种用法在只用于数字间的交换时,性能也不弱

第十种:利用eval计算

适用性: 仅适用于数字和字符串
代码如下:

eval("a="+b+";b="+a);

简要说明:
这种方式仅用于研究,实战慎用

这种模式执行一万次耗时等于其它执行一亿次...

第十一种:数组中,利用splice交换两个元素的位置

适用性: 仅适用于数组元素
代码如下:

arr[0] = arr.splice(2, 1, arr[0])[0];

简要说明:
这种方式看起来挺优雅的,但实际上性能远远比不上临时变量那种

各种交换方式的性能对比

上述列举了几种方式都有一一做过对比分析,基本上可以得出的结论是:

还是老老实实的用回临时变量交换吧,经典,优雅,而且保证不会出什么幺蛾子

性能对比截图

分析结果1

以下截图中的数据是,在chrome中运行了一亿次后得出的结论(每次运行100万次,一共100个循环,得到的分析结果)

可以看出,tmp变量交换最快,try catch最慢

分析结果2

以下截图数据是,在chrome (支持es6)中运行了100万次后得出的结论(每次运行1万次,一共100个循环,得到的分析结果)

可以看出,eval最慢,splice性能较低,tmp变量交换很稳定

分析工具示例Demo

如下demo中可以使用分析工具进行 JS变量交换方式分析对比

JS几种数值交换方式分析比较

参考

Exchange Variables Gracefully

JS几种变量交换的更多相关文章

  1. JS几种变量交换方式以及性能分析对比

    前言 "两个变量之间的值得交换",这是一个经典的话题,现在也有了很多的成熟解决方案,本文主要是列举几种常用的方案,进行大量计算并分析对比. 起由 最近做某个项目时,其中有一个需求是 ...

  2. JS几种数组遍历方式以及性能分析对比

    前言 这一篇与上一篇 JS几种变量交换方式以及性能分析对比 属于同一个系列,本文继续分析JS中几种常用的数组遍历方式以及各自的性能对比 起由 在上一次分析了JS几种常用变量交换方式以及各自性能后,觉得 ...

  3. JS变量和变量交换的三种方法

    一.what 变量就是用来存储数据的容器 二.how 通过var 关键字定义一个变量 var n1; //定义变量 变量的赋值:通过赋值运算符“=” 给变量赋值. var n2=123; //定义变量 ...

  4. 两个变量交换的四种方法(Java) 七种方法(JS)

    两个变量交换的四种方法(Java)   对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) 1 class TestEV 2 ...

  5. 两个变量交换的四种方法(Java)

    对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...

  6. JavaScript 基础——使用js的三种方式,js中的变量,js中的输出语句,js中的运算符;js中的分支结构

    JavaScript 1.是什么:基于浏览器 基于(面向)对象 事件驱动 脚本语言 2.作用:表单验证,减轻服务器压力 添加野面动画效果 动态更改页面内容 Ajax网络请求 () 3.组成部分:ECM ...

  7. 手写面试编程题- 数组去重 深拷贝 获取文本节点 设置奇数偶数背景色 JS中检测变量为string类型的方法 第6题闭包 将两个数组合并为一个数组 怎样添加、移除、移动、复制、创建和查找节点? 继承 对一个数组实现随机排序 让元素水平 垂直居中的三种方式 通过jQuery的extend方法实现深拷贝

    第1题==>实现数组去重 通过 new Set(数组名) // var arr = [12, 12, 3, 4, 5, 4, 5, 6, 6]; // var newarr1 = new Set ...

  8. javascript语法 1.运算符 2. 流程控制 3. 函数 4. 四种变量 5. 数据类型的运用 6. js页面交互

    1.运算符 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...

  9. 5、前端--js常量、变量、5种基本数据类型(number string boolean undefined object)、运算符、流程控制、三元运算符、函数、自定义对象、内置对象、BOM操作

    变量与常量 在JS中声明变量需要使用关键字 老版本 var(全部都是全局变量) 新版本 let(可以声明局部变量) # 推荐使用let(其实问题不大) 在JS中声明常量也需要使用关键字 const # ...

随机推荐

  1. MT【203】连续型的最值

    (北大自招)已知$-6\le x_i\le 10 (i=1,2,\cdots,10),\sum\limits_{i=1}^{10}x_i=50,$当$\sum\limits_{i=1}^{10}x^2 ...

  2. MT【166】青蛙跳

    (2015浙江重点中学协作体一模) 设ABCDEF为正六边形,一只青蛙开始在顶点A处,它每次可随意地跳到相邻两顶点之一.若在5次之内跳到D点,则停止跳动:若5次之内不能到达D点,则跳完5次也停止跳动. ...

  3. 【BZOJ4444】国旗计划

    Description 题目链接 Solution 磕了3个半小时没做出来的题,就是全场崩. 首先对于一个人的答案是很好求的,显然是选择左端点在此人区间中,右端点最远(最靠右)的人作为下一个接棒人.因 ...

  4. 缓存面板获取之前页面选中的数据Objuid的方法

    String partUid = request.getParameter("contextInstanceUid"); contextInstanceUid是存在总线总的键名,存 ...

  5. SQL Server 数据库对象命名参考

    一. 引言 编码规范是一个优秀程序员的必备素质,然而,有很多人非常注重程序中变量.方法.类的命名,却忽视了同样重要的数据库对象命名.这篇文章结合许多技术文章和资料,以及我自己的开发经验,对数据库对象的 ...

  6. C语言复习---获取最大公约数(辗转相除法和更相减损法)

    源自:百度百科 辗转相除法 辗转相除法:辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里德算法. 例如,求(,): ∵ ÷=(余319) ∴(,)=(,): ∵ ÷=(余58) ∴(,)=( ...

  7. SpringBoot入门Demo(Hello Word Boot)

    Spring Boot 是由Pivotal团队提供的全新框架,其设计目的是用来简化新的Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. ...

  8. [转载]微软VS2015支持Android和iOS编程

    Visual Studio 2015 Preview http://www.zhihu.com/question/26594936/answer/33397319 http://www.visuals ...

  9. Web性能优化系列(1):Web性能优化分析

    本文由 伯乐在线 - 鸭梨山大 翻译,sunbiaobiao 校稿.未经许可,禁止转载!英文出处:gokulkrishh.github.io.欢迎加入翻译小组. 如果你的网站在1000ms内加载完成, ...

  10. Hash::make与Hash::check

    调用方法之前要先去引用: use Illuminate\Support\Facades\Hash; 可以调用 Hash 门面上的 make 方法对存储密码进行哈希: $pwd = Hash::make ...