2024-05-29
Nano ID というライブラリを見つけて、どのようなものなのか気になったので調べてみた。
UUID v4 と比べ、Nano ID は 4bit 分ランダムな値が多い。
それでいて、UUID v4 の36文字に比べ、Nano ID は21文字と少ない文字数で表現できる。
Comparison with UUID
Nano ID is quite comparable to UUID v4 (random-based). It has a similar number of random bits in the ID (126 in Nano ID and 122 in UUID), so it has a similar collision probability:
Note: UUID はバージョン情報に 6bit 使用するため、128bit - 6bit で 122bit しかない。また、決まった位置に -
が含まれる。
A-Za-z0-9_-
で構成されている。URL Safe になっているので使いやすそう。
文字種を指定して使用することも可能。
// https://github.com/ai/nanoid/blob/36b05dd67bad457638958acff10fba04f747840f/README.md#custom-alphabet-or-size
import { customAlphabet } from 'nanoid'
const nanoid = customAlphabet('1234567890abcdef', 10)
model.id = nanoid() //=> "4f90d13a42"
そこまで時間がかかる処理ではないと思うが、crypto.randomUUID
に比べると 1/4 ぐらいなので、必要がなければ無理に使わなくて良さそう。
crypto.randomUUID 28,398,328 ops/sec
uuid v4 10,254,199 ops/sec
...
nanoid 7,484,029 ops/sec
customAlphabet 4,867,017 ops/sec
nanoid for browser 609,426 ops/sec
...
https://github.com/ai/nanoid/blob/36b05dd67bad457638958acff10fba04f747840f/README.md#benchmark
以下の簡単なコードを作って検証してみました。
https://gist.github.com/mryhryki/bf2c7b2e0e0998cea728ba879e5cf255
結果は nanoid()
が一番速かったです。
$ npm start >/dev/null
[Generate 1000000 IDs, Node.js version: v20.14.0]
#crypto.generateRandomUUID(): 1408.667041ms
#crypto.getRandomValues() : 2624.5462079999998ms
#nanoid() : 1425.9569999999994ms
README を見ると、crypto.generateRandomUUID()
が一番速いと書いてあるのですが、nanoid()
とほぼ差がなかったです。
標準出力に全て出しているので、文字数の多さが影響したのかもしれません。
そこまでの厳密性は求めないので、一旦これ以上は検証しないことにします。
UUID v4 とほぼ同じランダム性を持ちつつ、文字数が少なく、URL Safe な文字列で扱える便利なID生成ライブラリのようです。
生成速度も早く、ある程度カスタマイズもできるので、使えそうな機会には検討しても良さそうだな、と思いました。