UTAU音源をメモリ上に展開したら速いんじゃないのっていうの

いわゆるDLL音源と呼ばれる技術から、いろいろやってみたけど無意味だった話の経緯

私がUTAUを使っていると、resamplerが、合成の部分ではなく、IOの部分で躓いてよく止まっていたので、「20~100MB程度のバイナリデータなら、予めメモリ上に全部展開してからアクセスしたらもっとスムーズに動くんじゃないのかなーーーー」という発想をしたところがことの発端

前提

  • あんまりむずかしいプログラムをかきたくないのでC++/CLIのdllと、C#.NETの常駐プロセスでさっくり試した(←ここが失敗の始まり)
  • wavファイルをメモリ上に展開する等の動作は、あらかじめしておく
  • 計測は「あいうえおかきくけこさしすせそ」(すべて4分音符C4、BPM120)の合成を10回する中で、最初の合成が始まった瞬間から、再生が始まった瞬間まで。デフォルトを使った

実験

と、いう感じでMMFやパイプで試しながら、遅いなーと思いながら、私は気づいてしまった。
そもそもDLLのロードアンロードのコストがあることを……

dllも何もない素の状態

結果 (単位:ms)

2090.29886937177
2005.03347237748
2445.93400634466
2016.9324813351
1984.79209948685
2132.71717131112
2223.29230433249
1984.34192373584
2000.09864522473
2036.18255524774

だいたい2秒くらい

そもそもDLLのコスト

getpcmでreturn NULL;するだけの無意味なdllを読み込ませただけのもので、

結果 (単位:ms)

2837.50451529985
2731.31464148876
2777.5712690366
2666.00152415425
2706.47058504886
2692.46182272997
2690.22690967604
2715.01936268913
2718.66011274636
2699.10013317105

だいたい2.7秒くらい
悲しいかなつまり、DLLのロードアンロードの流れで少なくとも(今回の条件では)0.7秒は余計にかかり、ここが無視できないほどに大きい値である限り、いくらIOのコスト減らせるとはいえ、無意味っぽい、というところ(マネージでは)


ちなみに、この後C++で同じ無意味なdllを作って計測したところ、

結果 (単位:ms)

2101.99545604742
2060.90914974374
2033.58043106823
2082.54153434379
2020.85548217985
2069.27973875551
2035.4238993431
2038.43343400278
2057.6259173507
2083.46811521192

さしさわりがない結果が出てしまう

結論

UTAUのdllを作るときはネイティブで書こう。

同じような実装をC++ですれば速くなるような気もするけど、またやる気が出たときに