LoginSignup
0
0

More than 5 years have passed since last update.

native addonによる応答のバイナリ化・続き

Last updated at Posted at 2016-12-29

目的

「ゲームのサーバとしてNode.jsを使っていたのですが、応答のバイナリ化についてnative addonでどれだけ処理が改善できるのか」を証明しようと意気込んだadvent calendar向け実験した結果が余りに夢がなかったので、今年のうちにもう少し夢を追ってみることにしました。

追試

この実験からさらにパフォーマンスを上げる方向で調整し、ここまで改善しました。
- v8::Object::Get()で使用するkeyをあらかじめ用意する
- v8::String::WriteUtf8()が重いのでASCII文字が担保されている文字列はWriteOneByte()に任せる(UUIDとか)

そもそもサンプルデータの作り方もよくなかったのでJSON.stringifyの方の処理時間も下がっていますが、native addonが重い状況は変わりません。以前の2倍超よりは収まっているようです。

num items JSON.stringify native addon
100 34.342ms 53.611ms
200 62.441ms 105.324ms
300 93.283ms 158.426ms
400 122.436ms 199.763ms
500 158.034ms 263.912ms
600 186.730ms 323.354ms
700 213.992ms 378.184ms
800 242.050ms 474.247ms
900 270.003ms 451.293ms
1000 305.387ms 494.912ms

どこがボトルネックになっているのか一つ一つ処理を落としながら眺めていたのですが、どうもv8::Object::Get()が思いのほか重い。これは引数でObjectを渡しているのが良くなさそうです。

PLAYERDATA,ITEMDATAそれぞれバイナリ化する機能を分け引数の渡し方も文字か数値のみにするようにすれば、もう少し改善できるのでは…とも思いましたが、そうすると最終的にPLAYERDATA,ITEMDATAを連結しLOGINDATAを作るのはjs側になり「LOGINDATAをnative addonで作る」という趣旨から離れてしまいます。
現状は現状で1call辺り1msec以下で十分軽量であること、応答したバイナリはクライアントでデシリアライズすることなく素で使えること(=サーバは負荷増だがクライアントサイドのCPUリソース負荷軽減)を考えると、これはこれでよいのではないかとも思います。

addonの実装を最小単位にしてみる

ということで趣旨から離れてPLAYERDATA,ITEMDATA変換をaddonで実装しjs側で連結する、という手法を試してみました…が、結果はnative addonで全実装するよりも遅くなりました。

追いかけてみたところ返り値のBufferを作るNan::CopyBuffer((char*)buf, sizeof_buf)ここもまた重いポイントになっていました。最小単位にしてもアイテム数分callされることになり、結果として時間がかかるようになったと思われます。

num items use minimal addon
100 118.767ms
200 194.401ms
300 279.565ms
400 374.365ms
500 464.634ms
600 580.934ms
700 660.586ms
800 756.732ms
900 844.234ms
1000 938.798ms

breによるバイナリ化

趣旨から離れるのであれば、コメントでいただいたbreによるバイナリ化でnode.js側で実装することも選択になると思います。こちらについても実装してみました…が、結論としては処理に時間がかかりそうでした。

num items use bre
100 1135.328ms
200 2135.037ms
300 3152.748ms
400 4175.101ms
500 5222.016ms
600 6201.442ms
700 7396.662ms
800 32462.285ms
900 36018.517ms
1000 39275.021ms

defineObjectRecord(),view()値の書き込みに時間がかかっている印象でした。
使い方が良くないかもしれません。

結論

  • 引数がObjectの場合、値取得のアクセスが重くなる。
  • 応答バイナリはBufferで返す必要があり、この生成も重い。応答データはなるべく1つの関数内で作成を済ませたほうが良い。かつなるべく引数はObjectで渡さないほうが良い。
  • サーバのCPUリソースを使ってクライアントのCPUリソースを空ける、という意味では、native addonでの応答バイナリ化は良い選択かもしれない。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0