栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

基于 Rust 重新实现的 nanoid —— 性能居然提升了 40+%

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于 Rust 重新实现的 nanoid —— 性能居然提升了 40+%

笔者在跟随 Rust 重写一切的风气下 基于 Rust 实现了 napi-nanoid

在 node 环境下相比原版 nanoid.js 性能提升 40+%

跑分: Linux x64 gnu, Intel® Xeon® Platinum 8370C CPU @ 2.80GHz, Node.js 16.15.1 (runs: 6842925183)

目录
    • 挑选技术栈
    • 创建 `napi-rs` 工程
    • 基于 Rust 实现 nanoid 生成逻辑
      • 实现调用方法入口
      • 实现最核心的 `format` 逻辑
    • 通过 benchmark 对比性能
      • 通过 `benny` + `bench` 实现性能测试脚本
      • 和原版性能对比
      • 和各种随机 id 生成库性能对比
    • 发布到 10+ 不同的平台
    • 仓库链接

挑选技术栈

笔者这里选择了 napi-rs 的作为基础实现 napi-nanoid;
选择该技术栈的原因有两方面

  1. napi-rs 基于 Rust 生态,在实现 native NAPI 模块时可以更少考虑如 C++ 中内存申请释放的负担。

  2. napi-rs 的官方文档非常完整,提供了多个优秀的实践示例。

官网: napi.rs

创建 napi-rs 工程

基于 napi-rs/package-template

.
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── README.md
├── __test__ // 单元测试
├── benchmark // 性能测试
├── build.rs
├── index.d.ts
├── index.js
├── npm // 多平台入口
├── package.json
├── rustfmt.toml
├── src // source
├── tsconfig.json
└── yarn.lock
基于 Rust 实现 nanoid 生成逻辑 实现调用方法入口

调用方法设计了 .nanoid() 和 .non_secure() 高安全和非安全两个方法;
这里两个方法的设计参考了 nanoid.js

#[napi]
pub fn nanoid() -> String {
  format(nanoid::rngs::default, &nanoid::alphabet::SAFE, 21)
}

#[napi]
pub fn non_secure() -> String {
  format(nanoid::rngs::non_secure, &nanoid::alphabet::SAFE, 21)
}
实现最核心的 format 逻辑

实现过程中用到了宏来提供随机数生成的缓冲区;这里的实现思路也是参考了 nanoid.js

fn format(random: fn(usize) -> Vec, alphabet: &[char], size: usize) -> String {
  let bytes = &mut POOL.lock().unwrap();
  let mask = alphabet.len().next_power_of_two() - 1;

  let mut pointer = *POOL_OFFSET.lock().unwrap();
  let mut id = String::with_capacity(size);

  while id.len() < size {
    if pointer == POOL_SIZE {
      let buf = random(POOL_SIZE);
      for i in 0..POOL_SIZE {
        bytes[i] = buf[i];
      }
      pointer = 0;
    }
    let byte = bytes[pointer] as usize & mask;
    if alphabet.len() > byte {
      id.push(alphabet[byte]);
    }
    pointer += 1;
  }

  *POOL_OFFSET.lock().unwrap() = pointer;

  id
}

ps: 这里也同 nanoid.js 一样使用了 128 倍长度的缓冲空间

const POOL_SIZE_MULTIPLIER: usize = 128;
const DEFAULT_SIZE: usize = 21;
const POOL_SIZE: usize = DEFAULT_SIZE * POOL_SIZE_MULTIPLIER;

lazy_static! {
  static ref POOL: Mutex<[u8; POOL_SIZE]> = Mutex::new([0; POOL_SIZE]);
  static ref POOL_OFFSET: Mutex = Mutex::new(POOL_SIZE);
}
通过 benchmark 对比性能 通过 benny + bench 实现性能测试脚本
import benny from 'benny'
import benchmark, { Event } from 'benchmark'
const bench = new benchmark.Suite()

可参考代码: benchmark/bench.ts

和原版性能对比
  js-nanoid:
    3 392 881 ops/s, ±0.55%

  napi-nanoid:
    5 113 763 ops/s, ±0.12%

  js-nanoid (non-secure):
    1 875 245 ops/s, ±0.14%

  napi-nanoid (non-secure):
    5 237 554 ops/s, ±0.11% 

ps: 可以看出 napi-nanoid 版相比 js-nanoid 版本不管在安全还是非安全场景下都至少提升了 40+% 的性能表现。

跑分: (runs: 6842925183)

和各种随机 id 生成库性能对比
shortid                      24,084 ops/sec
cuid                        105,736 ops/sec
secure-random-string        207,409 ops/sec
uuid                        840,460 ops/sec
js-nanoid (non-secure)    1,826,354 ops/sec
js-nanoid (secure)        3,171,036 ops/sec
napi-nanoid (secure)      4,837,387 ops/sec
napi-nanoid (non-secure)  4,977,971 ops/sec
crypto.randomUUID        12,152,367 ops/sec
hyperid                  16,554,640 ops/sec

跑分: Linux x64 gnu, Intel® Xeon® Platinum 8370C CPU @ 2.80GHz, Node.js 16.15.1

跑分: (runs: 6842925183)

发布到 10+ 不同的平台

这里直接通过 napi-rs 官方的脚手架 + github workflow 实现发布到多个平台

node12node14node16
Windows x64✓✓✓
Windows x32✓✓✓
Windows arm64✓✓✓
macOS x64✓✓✓
macOS arm64✓✓✓
Linux x64 gnu✓✓✓
Linux x64 musl✓✓✓
Linux arm gnu✓✓✓
Linux arm64 gnu✓✓✓
Linux arm64 musl✓✓✓
Android arm64✓✓✓
Android armv7✓✓✓
FreeBSD x64✓✓✓

ps: 使用时无需关注平台 依然仅需引用 napi-nanoid 的 npm 入口包即可

const { nanoid } = require('napi-nanoid');

nanoid() // => AeogKAGjUMX6mqB4sMzWe
仓库链接

Repo: rustq/napi-nanoid

欢迎交流讨论 欢迎大家的 ☆ 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/974905.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号