tiktoken 3.8.0

A high-performance pure-Rust implementation of OpenAI's tiktoken BPE tokenizer
Documentation
//! Same-machine comparison harness for the Unicode-path work.
//!
//! Mirrors `web/bench/bench.ts` exactly — same corpora (the `varied`
//! generator is reproduced byte-for-byte), same shape of timing (warmup, then
//! median of 9 rounds) — so a native number and a browser number from the same
//! machine are directly comparable. Absolute README numbers still come from
//! the mini; this exists to attribute changes, not to publish.
//!
//!   cargo run --release --example stage_bench

use std::time::Instant;

fn varied(n: u32) -> String {
    let mut s = String::new();
    let mut x: u32 = 12345;
    let blocks = [
        (0x4e00u32, 0x9fa0u32),
        (0x3040, 0x30a0),
        (0xac00, 0xd780),
        (0x620, 0x650),
    ];
    for i in 0..n {
        x = x.wrapping_mul(1103515245).wrapping_add(12345);
        let (lo, hi) = blocks[((x >> 7) % 4) as usize];
        s.push(char::from_u32(lo + ((x >> 9) % (hi - lo))).unwrap());
        if i % 7 == 6 {
            s.push('\u{ff0c}');
        }
        if i % 23 == 22 {
            s.push(' ');
        }
    }
    s
}

fn main() {
    let cases: Vec<(&str, String)> = vec![
        ("short_13b", "Hello, world!".into()),
        (
            "medium_900b",
            "The quick brown fox jumps over the lazy dog. ".repeat(20),
        ),
        (
            "long_45kb",
            "The quick brown fox jumps over the lazy dog. ".repeat(1000),
        ),
        (
            "unicode_4kb",
            "你好世界!こんにちは世界!안녕하세요 세계!مرحبا بالعالم ".repeat(50),
        ),
        ("unicode_varied_4kb", varied(1200)),
        (
            "zh_prose_4kb",
            "分词器把文本切成 token,模型按 token 计费。同一段话在不同词表下的 token 数可能相差一倍以上,因此计费、上下文上限和截断位置都取决于分词是否准确。本实现覆盖多家厂商的编码,每一套都与参考实现逐字节比对,至今没有发现分歧。速度来自手写的扫描器:常见片段不进正则引擎,词级片段在栈上合并,零分配。"
                .repeat(10),
        ),
        (
            "ja_prose_4kb",
            "トークナイザーはテキストをトークンへ分割し、モデルはトークン単位で課金します。同じ文章でも語彙が違えばトークン数は大きく変わるため、分割の正確さは請求額と文脈上限に直結します。本実装は各ベンダーのエンコーディングを収録し、いずれも参照実装とバイト単位で照合済みです。速度は手書きスキャナによるもので、一般的な断片は正規表現エンジンを通しません。"
                .repeat(9),
        ),
        (
            "code_3kb",
            "def fibonacci(n):\n    if n <= 1:\n        return n\n    return fibonacci(n - 1) + fibonacci(n - 2)\n\n# compute first 100 fibonacci numbers\nresults = [fibonacci(i) for i in range(100)]\nprint(results)\n".repeat(20),
        ),
    ];
    let enc = tiktoken::get_encoding("cl100k_base").unwrap();
    println!("{:<20}{:>12}  tokens", "corpus", "count()");
    for (name, text) in &cases {
        for _ in 0..50 {
            std::hint::black_box(enc.count(text));
        }
        let n = if text.len() < 100 {
            20000
        } else if text.len() < 2000 {
            2000
        } else {
            200
        };
        let mut runs = vec![];
        for _ in 0..9 {
            let s = Instant::now();
            for _ in 0..n {
                std::hint::black_box(enc.count(text));
            }
            runs.push(s.elapsed().as_nanos() as f64 / n as f64);
        }
        runs.sort_by(|a, b| a.partial_cmp(b).unwrap());
        println!("{name:<20}{:>10.0} ns  {}", runs[4], enc.count(text));
    }
}