JavaScript

Array.prototype.hogehoge vs Lodash ~ 2018年でもLodashは速いのか? ~

なんか枠が空いているので、2回目の投稿です。JavaScriptの話です。1回目の投稿とはなんの関係もないです。


2016年はLodashのほうが速かった・・・らしい

みんな大好きLodash。皆さん使ってますか?

私は主にオブジェクトをcloneDeepするのに使ってます。乱用すると重くなるのがアレですが、でも標準でDeepCopyする機能ないんだもん、しょうがないよね。

しかしながらそんなLodashもES6からmapforEachfilterなど、主に配列操作でよく使う関数たちが標準実装されるようになり、だんだん影が薄くなってきました。

でも、そんな状況でもあえて標準のmapではなくLodashのmapこともあるようです。何故かと言うと実行速度が違うから。例えば2016年に書かれたこの記事では標準のmapに比べてLodashのmapはだいたい5倍ぐらい速いと書かれています。なるほど、2016年はそうだったのか。

しかし、今はもう2018年も終わりを迎えようとしています。きっと標準のmap関数も最適化が進んで速くなっているはず!

というわけでベンチマークを取ってみました。

今回はMeasureThat.netというサイトと使ってベンチマークを取ります。これはブラウザ上でBenchmarkJS (v.2.1.1) を動かすことができるWebアプリです。便利


Map

https://www.measurethat.net/Benchmarks/Show/4353/0/arrayprototypemap-vs-lodash-map

実行コード

const array = [...Array(100000).keys()];

array.map(n => n*2) // Array.protptype.map
_.map(array,n => n*2) // lodash map


chrome

スクリーンショット 2018-12-10 01.34.29.png


Firefox

スクリーンショット 2018-12-10 01.35.24.png


Safari

スクリーンショット 2018-12-10 01.36.42.png

Mapは全体的にLodashのほうが速そうですね。特にChrome環境下で差が顕著です


forEach

https://www.measurethat.net/Benchmarks/Show/4354/0/arrayprototypeforeach-vs-lodash-foreach

const array = [...Array(100000).keys()];

array.forEach(n => n*2) // Array.protptype.forEach
_.forEach(array,n => n*2) // lodash forEach


chrome

スクリーンショット 2018-12-10 01.27.56.png


Firefox

スクリーンショット 2018-12-10 01.29.19.png


safari

スクリーンショット 2018-12-10 01.33.36.png

なんかforEachは標準の関数のほうが速そうです。なんで違うねん。特にFirefoxで差が大きいです


filter

https://www.measurethat.net/Benchmarks/Show/4386/0/arrayprototypefilter-vs-lodash-filter2

実行コード

const array = [...Array(100000).keys()];

const ram = Math.floor(100000 * Math.random());
array.filter(n => n === ram) // Array.prototype.filter
_.filter(array,n => n === ram) // Lodash filter


chrome

スクリーンショット 2018-12-10 01.21.23.png


Firefox

スクリーンショット 2018-12-10 01.22.12.png


safari

スクリーンショット 2018-12-10 01.26.40.png

filterはどちらもあまり変わらないですね。ブラウザによって早かったり遅かったりです。


find

https://www.measurethat.net/Benchmarks/Show/4387/0/arrayprototypefind-vs-lodash-find2

実行コード

const array = [...Array(100000).keys()];

const ram = Math.floor(100000 * Math.random());
array.find(n => n === ram) // Array.prototype.find
_.find(array,n => n === ram) // Lodash find


chrome

スクリーンショット 2018-12-10 01.13.41.png


Firefox

スクリーンショット 2018-12-10 01.14.39.png


safari

スクリーンショット 2018-12-10 01.18.59.png

findも傾向としてはfilterと似たような感じ。Firefox環境下では標準の関数のほうが速そうです。


some

https://www.measurethat.net/Benchmarks/Show/4388/0/arrayprototypesome-vs-lodash-some2

実行コード

const array = [...Array(100000).keys()];

const ram = Math.floor(100000 * Math.random());
array.some(n => n === ram) // Array.prototype.some
_.some(array,n => n === ram) // Lodash some


chrome

スクリーンショット 2018-12-10 01.08.12.png


Firefox

スクリーンショット 2018-12-10 01.12.04.png


safari

スクリーンショット 2018-12-10 01.11.00.png

違いがわからない


every

https://www.measurethat.net/Benchmarks/Show/4389/0/arrayprototypeevery-vs-lodash-every2

実行コード

const array = [...Array(100000).keys()];

const ram = Math.floor(100000 * Math.random());
array.every(n => n === ram) // Array.prototype.every
_.every(array,n => n === ram) // Lodash every


chrome

スクリーンショット 2018-12-10 01.03.13.png


Firefox

スクリーンショット 2018-12-10 01.07.16.png


safari

スクリーンショット 2018-12-10 01.06.15.png

everyは標準の関数のほうが速そうです。


まとめ

以上、私が普段よく使うものだけまとめましたが、map以外は標準のものを使っていれば良さそうですね。

ただ、今回は性能が問題になりそうなモバイルブラウザでは測定していないですし、babelでトランスコンパイルしていたりするとまた違った結果になりそうなので、あくまで参考です。

まあぶっちゃけ、frontでめちゃめちゃ重い計算処理をすることってあまりないですし、DOM描画のほうが実行コスト高くなりがちなので、実際のプロジェクトではあまり気にしなくても良いのかもしれません。