あらすじ
他人が書いている javascript のコードを見てたらチルダの使い方が面白かったので紹介します。
~(チルダ)についておさらい
~ ってbit反転するアレなんだけど javasciript だとたまにこんな記述があるので覚えておくと良いです。
if ( ~['a', 'b', 'c'].indexOf('b') ) { console.log('exist'); }
以下と同等です。
if ( ['a', 'b', 'c'].indexOf('b') !== -1 ) { console.log('exist'); }
DeNADev / Arctic.js を眺めていた
そしたら以下のような記述があるんですよ。
x = ~~(x * scale);
なんとなく Math.Round の代用をしている様にも見える
console.log( ~~(10.1) ); // 10 console.log( ~~(10.9) ); // 10
Math.Round vs hack
こんなのとか http://www.slideshare.net/madrobby/extreme-javascript-performance
こんなのとか http://jsperf.com/math-round-vs-hack/48
結論
まあサーバーサイドエンジニアであんまりここがボトルネックになることないので気にしなくてもいいんじゃないかなあ。
一応以下のようにベンチとったけど。とりあえず~~はなんとなく Math.ceil やらを書いた時にこういった書き方もあるんだっけなあとか思い出してもいいんじゃないっすかね。
// !node-bench % // run many times so that we can abstract out the overhead of promise creation. //exports.countPerLap = count; exports.compare = { MathRound: function(done) { var somenum = -500 + (Math.random() * 1000); var rounded = Math.round(somenum); done(); }, hack: function(done) { var somenum = -500 + (Math.random() * 1000); var rounded = ~~(somenum); done(); } };
結果
Please be patient. Scores: (bigger is better) hack Raw: > 629.7572427572428 > 635.9070929070929 > 648.3326673326674 > 632.924075924076 > 604.005994005994 Average (mean) 630.1854145854147 MathRound Raw: > 554.048951048951 > 562.027972027972 > 545.2057942057942 > 541.2377622377622 > 462.27172827172825 Average (mean) 532.9584415584416 Winner: hack Compared with next highest (MathRound), it's: 15.43% faster 1.18 times as fast 0.07 order(s) of magnitude faster