Node.jsのN-APIをRustから使ってみた。
Node.jsにてRustのプログラムをffiしたいと思い、node-ffiを調べてみたが、しばらく更新されておらず、Node.js 12以降だと利用できない模様。
GitHub - node-ffi/node-ffi: Node.js Foreign Function Interface
RPCではない方法で他に連携する方法はないかと調べてみた結果Node.jsにはネイティブアドオンを作成するためのAPIが用意されているらしい。
今回はこれをRustから利用できる形で提供してくれているnapi-rsを使用してみる。
今回検証する環境の各バージョン
- Windows 10 1909
- Node.js v14.15.0
- napi-rs 0.3.9
- Rust 1.47.0
- napi 0.5.1
- napi-derive 0.5.1
- napi-build 0.2.1
napi-rsのドキュメントに従いcargo buildしてみたところ以下のエラーが発生
thread 'main' panicked at 'Unable to find libclang: "couldn\'t find any valid shared libraries matching: [\'clang.dll\', \'libclang.dll\'], set the
LIBCLANG_PATH
environment variable to a path where one of these files can be found (invalid: [])"'
clangが必要なようのでLLVMをインストール
今回インストールしたバージョンは11.0.0
The LLVM Compiler Infrastructure Project
他は特に問題なくcargo buildすることができた。
Node.jsからRustのfibonacci関数を呼び出すサンプル
Node.jsとRustのfibonacci関数を比較
PASS ./fib.test.js (14.479 s) √ fibonacci(30) for rust (3 ms) √ fibonacci(30) for js (16 ms) √ fibonacci(31) for rust (2 ms) √ fibonacci(31) for js (24 ms) √ fibonacci(32) for rust (3 ms) √ fibonacci(32) for js (39 ms) √ fibonacci(33) for rust (5 ms) √ fibonacci(33) for js (64 ms) √ fibonacci(34) for rust (13 ms) √ fibonacci(34) for js (102 ms) √ fibonacci(35) for rust (15 ms) √ fibonacci(35) for js (168 ms) √ fibonacci(36) for rust (26 ms) √ fibonacci(36) for js (263 ms) √ fibonacci(37) for rust (47 ms) √ fibonacci(37) for js (432 ms) √ fibonacci(38) for rust (68 ms) √ fibonacci(38) for js (701 ms) √ fibonacci(39) for rust (108 ms) √ fibonacci(39) for js (1119 ms) √ fibonacci(40) for rust (168 ms) √ fibonacci(40) for js (1828 ms) √ fibonacci(41) for rust (294 ms) √ fibonacci(41) for js (3061 ms) √ fibonacci(42) for rust (474 ms) √ fibonacci(42) for js (4855 ms)
Rust版のほうが概ね10倍程度は高速なようだ。 fibonacci関数は本来キャッシュすべきとか、Rust版は末尾再帰最適化がかかっているとかはあるがnapi-rsの検証が目的なのでパフォーマンスは次回以降にちゃんと検証したい。