マジでデノーマル
君はデノーマルを知っているか?
僕は知らなかったんだけど、簡単に言うとめっちゃ小さい数値の計算をしてたら遅くなる。
ここ や ここ が分かりやすい。
JavaScriptの信号処理の際は Float32Array を使うのが定番なので、Float32Array に代入しつつ検討してみた。
ここに二つのコードがある。
var a = new Float32Array(128), x = 1; for (var i = 0; i < 128; i++) { x *= 0.1; a[i] = x; }
これと
var a = new Float32Array(128), x = 1; for (var i = 0; i < 128; i++) { x *= 0.1; if ( (x > 0 && x < 1e-6) || (x < 0 && x > -1e-6) ) { x = 0; } a[i] = x; }
これ、どっちが速いか?
jsPerf で ベンチマーク をとってみました。
ベンチマークの結果、Float32Array の場合はフラッシュ処理 (小さかったら 0 にするやつ) を入れた方が速いし、 Float64Array の場合は何もしない方が速い。
ちなみに、デノーマル数が発生しないとき (* 0.1 じゃなくて * 0.99 するとか) の場合は当然何もしない方が速い。それでも Float32Array より Float64Array の方が若干速い。
JS内部の型のこともあると思うのだけど、デノーマル数をFloat32Arrayに代入するときのコストが大きい気がする。じゃあ信号処理するときは基本 Float64Array を使って最後だけ Float32Array を使うのがベストだと思うのだけど、どうなんでしょうか?貧者は死ぬしかないのでしょうか??