前言
“兩個變量之間的值得交換”,這是一個經典的話題,現在也有了很多的成熟解決方案,本文主要是列舉幾種常用的方案,進行大量計算並分析對比。
起由
最近做某個項目時,其中有一個需求是交換數組中的兩個元素。當時使用的方法是:
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變量交換很穩定
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。