音の鳴るブログ

鳴らないこともある

マジでデノーマル

君はデノーマルを知っているか?
僕は知らなかったんだけど、簡単に言うとめっちゃ小さい数値の計算をしてたら遅くなる
ここここ が分かりやすい。

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 を使うのがベストだと思うのだけど、どうなんでしょうか?貧者は死ぬしかないのでしょうか??