
2025/12/13 11:31
Lite^3, a JSON-compatible zero-copy serialization format
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Summary
Lite³ は、単一の連続バッファ内に B‑ツリーを格納するゼロコピー・バイナリシリアライゼーション形式です。スキーマレスで自己記述的であり、オプションの yyjson 依存関係を介して JSON への変換や逆変換が可能です。
主な特徴は次のとおりです:
- O(log n) のアクセスで任意のフィールドを読み書きでき、ゼロコピーで読込/書込します。
- コンパクトな C11 実装(約 9.3 kB)で MIT ライセンス。デフォルトではエラーメッセージは無効ですが、
または#define LITE3_ERROR_MESSAGES
を指定すると有効になります。-DLITE3_ERROR_MESSAGES - 2 つの API:Buffer API(呼び出し側がバッファを供給し malloc は不要)と Context API(メモリ割り当てを抽象化)。
- 強力なセキュリティ対策:境界チェック付きポインタ逆参照、実行時型安全性、再帰制限、および世代ポインタ。
- ベンチマークでは、Lite³ は SIMD JSON ライブラリより最大 120 倍、FlatBuffers より最大 242 倍の性能を示し、実際の Twitter API ペイロードで実証されています。グラフシリアライゼーションタスクでは、他フォーマット(66–1887 ms)に対して約 7–8 ms の高速処理が可能です。
- CPU 制限環境向けに設計されているものの、フィールド名を格納するため Protobuf より帯域幅を多く消費する場合があります。
インストールは
make install、pkg‑config サポート、または build/liblite3.a への手動リンクで簡単に行えます。将来の作業としては、ビルド最適化、GC‑index デフラグメンテーション、完全な JSON 相互運用性、キー衝突処理、圧縮ベンチマーク、言語バインディング、および正式仕様の策定があります。
Lite³ は高速でスキーマ不要のシリアライゼーションを最小限のコードフットプリントで提供し、組み込みシステム、帯域幅制限デバイス、高スループット API など効率的なメッセージングが求められる環境に魅力的な選択肢となります。
本文
TRON(旧名 Lite³):Tree Root Object Notation
解析は不要です―通信形式がそのままメモリ表現です。
公式ドキュメント
- ウェブサイト: lite3.io
- Lite³ の設計について詳しく読む
はじめに
Lite³ は、1 つの連続したバッファ内に B‑木をエンコードするゼロコピー二進数直列化フォーマットです。
任意のフィールドへ O(log n) 時間でアクセス・変更が可能なため、「パース」や「シリアライズ」が不要になります。
- スキーマレス & 自己記述 – IDL やスキーマ定義は必要ありません。
- JSON 変換 – メッセージのデバッグ/検査を簡単に行えます。
- 性能 – SIMD JSON ライブラリより最大120倍、Google Flatbuffers より最大242倍速いベンチマーク結果があります。
- 最小 C 実装 – 9.3 kB、外部依存なし。
特徴
| Feature | Description |
|---|---|
| Schemaless & self‑describing | スキーマ不要。 |
| Zero‑copy reads / writes | バッファ上で直接操作。 |
| O(log n) I/O operations | すべてのキー/値検索・更新が O(log n)。 |
| Built‑in pointer validation | B‑木を安全に辿れます。 |
| Low memory profile & predictable latency | 組込みシステム向け設計。 |
| No malloc API | 呼び出し側でバッファを用意。 |
| Library size 9.3 kB (core) | 依存なし、C11/GNU 構文。 |
| Optional JSON support | 経由で利用可。 |
| MIT license | オープンソース。 |
コード例
バッファ API(ゼロコピー)
#include <stdio.h> #include <string.h> #include "lite3.h" static unsigned char buf[1024], rx[1024]; int main(void) { size_t buflen = 0, bufsz = sizeof(buf); /* メッセージ構築 */ lite3_init_obj(buf, &buflen, bufsz); lite3_set_str(buf, &buflen, 0, bufsz, "event", "lap_complete"); lite3_set_i64(buf, &buflen, 0, bufsz, "lap", 55); lite3_set_f64(buf, &buflen, 0, bufsz, "time_sec", 88.427); printf("buflen: %zu\n", buflen); lite3_json_print(buf, buflen, 0); /* ラップ数更新 */ printf("\nUpdating lap count\n"); lite3_set_i64(buf, &buflen, 0, bufsz, "lap", 56); printf("Data to send:\nbuflen: %zu\n", buflen); lite3_json_print(buf, buflen, 0); /* 転送(memcpy) */ size_t rx_buflen = buflen, rx_bufsz = sizeof(rx); memcpy(rx, buf, buflen); /* 受信側で変更 */ printf("\nVerifying fastest lap\n"); lite3_set_str(rx, &rx_buflen, 0, rx_bufsz, "verified", "race_control"); lite3_set_bool(rx, &rx_buflen, 0, rx_bufsz, "fastest_lap", true); printf("Modified data:\nrx_buflen: %zu\n", rx_buflen); lite3_json_print(rx, rx_buflen, 0); return 0; }
出力
buflen: 154 { "lap": 55, "event": "lap_complete", "time_sec": 88.427 } Updating lap count Data to send: buflen: 154 { "lap": 56, "event": "lap_complete", "time_sec": 88.427 } Verifying fastest lap Modified data: rx_buflen: 197 { "lap": 56, "event": "lap_complete", "time_sec": 88.427, "fastest_lap": true, "verified": "race_control" }
コンテキスト API(メモリ管理型)
#include <stdio.h> #include "lite3_context_api.h" int main(void) { lite3_ctx *ctx = lite3_ctx_create(); /* メッセージ構築 */ lite3_ctx_init_obj(ctx); lite3_ctx_set_str(ctx, 0, "event", "http_request"); lite3_ctx_set_str(ctx, 0, "method", "POST"); lite3_ctx_set_i64(ctx, 0, "duration_ms", 47); /* ヘッダー設定 */ size_t headers_ofs; lite3_ctx_set_obj(ctx, 0, "headers", &headers_ofs); lite3_ctx_set_str(ctx, headers_ofs, "content-type", "application/json"); lite3_ctx_set_str(ctx, headers_ofs, "x-request-id", "req_9f8e2a"); lite3_ctx_set_str(ctx, headers_ofs, "user-agent", "curl/8.1.2"); /* JSON で表示 */ lite3_ctx_json_print(ctx, 0); /* user‑agent を取得 */ size_t ofs; lite3_ctx_get_obj(ctx, 0, "headers", &ofs); lite3_str user_agent = lite3_ctx_get_str(ctx, ofs, "user-agent"); printf("User agent: %s\n", LITE3_STR(ctx->buf, user_agent)); lite3_ctx_destroy(ctx); return 0; }
出力
{ "method": "POST", "event": "http_request", "duration_ms": 47, "headers": { "user-agent": "curl/8.1.2", "x-request-id": "req_9f8e2a", "content-type": "application/json" } } User agent: curl/8.1.2
はじめ方
ビルド & インストール
git clone https://github.com/fastserial/lite3.git cd lite3 # 静的ライブラリ(デフォルト) make all # liblite3.a をビルド # テスト実行 make tests # 例題をビルド make examples # /usr/local にインストール sudo make install -j sudo ldconfig
ライブラリ使用方法
/* バッファ API */ #include "lite3.h" /* コンテキスト API */ #include "lite3_context_api.h"
1 つのプログラムには 1 つだけヘッダをインクルードしてください。
エラーメッセージを有効化(任意)
#define LITE3_ERROR_MESSAGES /* lite3.h 内または -DLITE3_ERROR_MESSAGES で設定 */
フラグ変更後は再インストールが必要です。
フィーチャーマトリクス
| Format | Schemaless | Zero‑copy reads | Zero‑copy writes | Human‑readable |
|---|---|---|---|---|
| Lite³ | ✅ | O(log n) | O(log n) | ⚠️ (JSON 変換可) |
| JSON | ✅ | ❌ | ❌ | ✅ |
| BSON | ✅ | ❌ | ❌ | ⚠️ |
| MessagePack | ✅ | ❌ | ❌ | ⚠️ |
| CBOR | ✅ | ❌ | ❌ | ⚠️ |
| Flatbuffers | ❌ | O(1) | O(1) | ❌ (不変) |
(括弧内は元のドキュメントに記載された注釈を参照)
ベンチマーク
Simdjson Twitter API データベンチマーク
| Format | top_tweet | partial_tweets | find_tweet | distinct_user_id |
|---|---|---|---|---|
| yyjson | 205 426 ns | – | 203 147 ns | 207 233 ns |
| simdjson On‑Demand | 91 184 ns | 91 090 ns | 53 937 ns | 85 036 ns |
| Lite³ Context API | 2 285 ns | 17 820 ns | 456 ns | 11 869 ns |
Kostya JSON ベンチマーク(115 MB)
| Language / Library | Execution Time | Memory Usage |
|---|---|---|
| C/gcc (lite3) | 0.027 s | 203 MB |
| C++/g++ (simdjson On‑Demand) | 0.0759 s | 173 MB |
| … | … | … |
Cista++ シリアライゼーションベンチマーク
| Format | Serialize + Deserialize | Traverse | Message Size |
|---|---|---|---|
| Lite³ Buffer API | 7.79 ms | 79.39 ms | 38.069 MB |
| Lite³ Context API | 7.80 ms | 79.59 ms | 38.069 MB |
(詳細なベンチマーク表は元のドキュメントで確認可)
セキュリティ
- 境界チェック付きポインタ参照
- 実行時型安全性
- 再帰制限
- ダングリングポインタを防ぐ世代別ポインタマクロ
脆弱性はメンテナに報告してください。
FAQ
| 質問 | 回答 |
|---|---|
| JSON の代わりに使う? | C と高速化が必要なら有効です。そうでなければバインディングを待つ方が良いでしょう。 |
| Protocol Buffers を置き換える? | Lite³ は速いですが、自己記述キーのためワイヤサイズは大きくなります。CPU か帯域幅かで選択してください。 |
| 本番利用可能? | フィールドテスト済みですが、API が変更される場合があります。まず評価を行ってください。 |
| 組込み / ARM で使える? | と 8 バイト浮動小数点がサポートされていれば動作します。C99 でも可能(静的アサーション除外)。 |
ロードマップ
- ビルド最適化 (
)-flto - GC インデックス付き組み込み defragmentation
- 配列・入れ子オブジェクトを含む完全な JSON 相互運用性
コンパイルフラグの追加yyjson- キー衝突処理
- 圧縮ベンチマーク
- 言語バインディング
- 形式仕様書化
メーリングリスト
- 購読:
devlist-subscribe@fastserial.com - 配信停止:
devlist-unsubscribe@fastserial.com
クレジット
- Lite²(2024) by Tianyi Chen らからインスパイア。Lite³ は独立した実装です。
ライセンス: MIT(LICENSE を参照)。
yyjson も MIT ライセンスを含みます。