nodejs調(diào)用rust的完整代碼實例
nodejs調(diào)用rust
調(diào)用rust的方式目前分為打包dll庫調(diào)用和wasm
性能和跨平臺兼容性分別有不同優(yōu)缺點可根據(jù)各自需求
nodejs 調(diào)用rust的方式目前分為打包dll庫調(diào)用和wasm
1. 調(diào)用 Rust 打包的 DLL 庫
優(yōu)點:
- 性能更高:DLL 是直接編譯為本地機器代碼的動態(tài)鏈接庫,幾乎沒有額外的運行時開銷。
- 直接訪問系統(tǒng)資源:可以使用操作系統(tǒng)的底層功能,調(diào)用成本低。
- 適用于高性能需求:如果需要頻繁調(diào)用復雜的計算邏輯,DLL 是更優(yōu)的選擇。
- 跨語言調(diào)用成熟:通過 Node.js 的
ffi-napi或napi-rs等庫,可以高效與 Rust 的 DLL 交互。
缺點:
- 跨平臺兼容性復雜:需要為 Windows(DLL)、macOS(.dylib)和 Linux(.so)分別構建對應的動態(tài)庫。
- 部署復雜:需要在目標環(huán)境中正確配置動態(tài)庫的路徑。
- 線程安全性:如果你的 DLL 代碼設計不當,可能導致線程沖突。
2. 調(diào)用 Rust 編譯的 WASM
優(yōu)點:
- 跨平臺性:WASM 是平臺無關的,運行時在所有支持 WebAssembly 的環(huán)境中都一致。
- 容易部署:Rust 編譯為 WASM 后,生成一個
.wasm文件,可以直接加載,不需要擔心動態(tài)庫路徑。 - 安全性:WASM 在沙盒環(huán)境中運行,不直接訪問底層資源,隔離更好。
缺點:
性能開銷:
- WebAssembly 的沙盒環(huán)境導致運行時性能稍遜于本地代碼。
- 如果需要頻繁調(diào)用小粒度函數(shù),調(diào)用開銷可能顯著。
與 Node.js 的綁定層次較淺:通過
@wasmer/wasi或@wasm-tool/wasm-pack-plugin等工具加載后,可能需要額外處理復雜的內(nèi)存管理或數(shù)據(jù)交換問題。
性能比較
- 執(zhí)行效率: DLL > WASM
DLL 是本地執(zhí)行的動態(tài)鏈接庫,幾乎沒有額外開銷;WASM 有一定的沙盒化運行開銷。 - 調(diào)用成本: DLL < WASM
調(diào)用 DLL 是直接的本地調(diào)用,而調(diào)用 WASM 涉及到序列化和反序列化。 - 部署復雜性: DLL > WASM
DLL 需要根據(jù)操作系統(tǒng)生成多個文件,WASM 只需一個文件即可運行。
如果你的 Rust 邏輯以高密度計算為主,例如數(shù)據(jù)處理、壓縮等,推薦 DLL。如果是需要兼容多個環(huán)境,并且以一次性任務為主,推薦 WASM。
代碼示例
- 先寫點rust代碼,并自動開啟多線程處理數(shù)據(jù)
use rayon::prelude::*;
#[no_mangle]
pub extern "C" fn add_to_array(arr: *const i32, len: usize, num: i32, result: *mut i32) {
let slice = unsafe { std::slice::from_raw_parts(arr, len) };
let output = unsafe { std::slice::from_raw_parts_mut(result, len) };
// 并行操作輸出數(shù)組
output
.par_iter_mut()
.enumerate()
.for_each(|(i, out)| {
*out = slice[i] + num;
});
}
Cargo.toml 文件
[package]
name = "rust_napi"
version = "0.1.0"
edition = "2021"
[dependencies]
napi = { version = "2.11.0" }
rand = "0.8"
rayon = "1.7"
[lib]
crate-type = ["cdylib"] // mac 打包cdylib, windows 打包dll
如何將rust打包cdylib或者dll
// mac 指定架構 cargo build --release --target x86_64-apple-darwin // window cargo build --release
打包后會在當前目錄生成target文件夾
x86_64-apple-darwin這個文件夾就是打包后生成的指定架構的包

- node 調(diào)用cdylib,并執(zhí)行
node 調(diào)用cdylib需要使用到ffi-napi
// cargo build --release --target x86_64-apple-darwin
const path = require("path");
const ffi = require("ffi-napi");
const ref = require("ref-napi");
// 動態(tài)確定庫文件路徑 "/rust_napi/target/x86_64-apple-darwin/release/librust_napi.dylib"
const libName =
process.platform === "win32"
? "librust_napi.dll"
: process.platform === "darwin"
? "/rust_napi/target/x86_64-apple-darwin/release/librust_napi.dylib"
: "librust_napi.so";
const libPath = path.join(__dirname, libName);
// 加載 Rust 庫
const rustLib = ffi.Library(libPath, {
add_to_array: ["void", ["pointer", "size_t", "int", "pointer"]],
});
function addToArray(arr, num) {
const arrayLength = arr.length;
const inputBuffer = Buffer.alloc(arrayLength * 4); // 每個 i32 占 4 字節(jié)
const outputBuffer = Buffer.alloc(arrayLength * 4);
// 將 JavaScript 數(shù)組寫入輸入緩沖區(qū)
arr.forEach((value, index) => {
inputBuffer.writeInt32LE(value, index * 4);
});
// 調(diào)用 Rust 函數(shù)
rustLib.add_to_array(inputBuffer, arrayLength, num, outputBuffer);
// 從輸出緩沖區(qū)讀取結果數(shù)組
const result = [];
for (let i = 0; i < arrayLength; i++) {
result.push(outputBuffer.readInt32LE(i * 4));
}
return result;
}
const generateRandomIntArray = (size, min, max) => {
return Array.from({ length: size }, () =>
Math.floor(Math.random() * (max - min) + min)
);
};
let listy = generateRandomIntArray(4e7, 1, 100);
let start = Date.now();
addToArray(listy, 100);
console.log(Date.now() - start, 4); // rust 974
module.exports = { addToArray };
總結
到此這篇關于nodejs調(diào)用rust的文章就介紹到這了,更多相關nodejs調(diào)用rust內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Node.js使用NodeMailer發(fā)送郵件實例代碼
本篇文章主要介紹了Node.js使用NodeMailer發(fā)送郵件實例代碼,具有一定的參考價值,有興趣的可以了解一下。2017-03-03
nodejs?express路由匹配控制及Router模塊化使用詳解
這篇文章主要為大家介紹了nodejs?express路由匹配控制及Router模塊化使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
windows使用nvm對node進行版本管理切換的完整步驟
這篇文章主要介紹了windows使用nvm對node進行版本管理切換的完整步驟,在使用之前各位務必卸載掉自己安裝過的nvm或者node版本包括環(huán)境變量之類的,要保證自己的電腦完全沒有node環(huán)境,需要的朋友可以參考下2024-03-03
用node-webkit把web應用打包成桌面應用(windows環(huán)境)
這篇文章主要介紹了windows環(huán)境下用node-webkit把web應用打包成桌面應用的教程,需要的朋友可以參考下2018-02-02

