整数から文字列への変換(2014)

2026/10/19 8:08

整数から文字列への変換(2014)

RSS: https://news.ycombinator.com/rss

要約▶

Japanese Translation:

この本文の主なメッセージは、Lwan ウェブフレームワークにおいて、非効率な標準関数

snprintf()
を、除算操作を最小限に抑えるためのカスタムアルゴリズム(要素数 201 のルックアップテーブルを使用)で置き換えたことで、整数から文字列への変換の最適化により 31% のパフォーマンス向上が実現されたというものです。Core i7 システムでのベンチマークでは、初期のアプローチである
snprintf()
と naïve な逐次除算メソッドは、レスポンスヘッダー生成のような高スループットタスクには遅すぎることが示されました。配列のルックアップを加法に置き換えるという中間的な最適化で約 9% の速度向上は達成できましたが、完全なルックアップテーブルアプローチが最大の利点をもたらしました。Facebook Engineering の実装(このルックアップテーブルを使用)はライセンスの問題により Lwan に直接採用することはできませんが、その手法は有効であり、適応可能です。開発者は、
MAX_INT
サイズのバッファに対して
numeric_limits<uint32_t>::digits10
などの標準定数を使用してサイズを簡素化し、複雑な実行時計算を回避できます。このケースは、汎用ライブラリ呼び出しをカスタムルックアップテーブルに置き換えることで、コア機能の犠牲なしに著しい速度向上をもたらすことができることを示しています。

本文

インターネットスケールな整数文字列変換の進化:Lwan と Facebook のアプローチ

はじめに

整数を文字列表現に変換する処理は、ボトルネックにはなりにくいが、特定のアプリケーション(例:レスポンスヘッダー構築)では頻出します。Lwan などの高性能 Web サーバー開発において、この性能向上への取り組みは重要です。

Lwan のアプローチの進化

1.
snprintf()
の使用

当初は標準関数

snprintf()
が用いられていました。

  • 機能としては問題ありませんでした。
  • しかし、パフォーマンス観点では極めて無味乾燥なアプローチとされました。

2. ナイーブ(単純)アルゴリズム

次に試されたのは「数を 10 で順次割り、剰余で文字列へ逆順書き込み、最後に反転させる」手法です。

// 参照元:https://code.google.com/p/stringencoders/
size_t naive_uint32_to_str(uint32_t value, char *str) {
    char *wstr = str;
    // 変換処理:数字は逆順になる
    do
        *wstr++ = (char) decimal_digits[uvalue % 10];
    while (uvalue /= 10);
    *wstr = '\0';
    // 文字列を反転(ここがパフォーマンスのボトルネック)
    strreverse(str, wstr - 1);
    return wstr - str;
}

3. 最適化:逆順書き込みの実装

「変換後に反転させる」のではなく、最初から逆順に書き込む手法に変更しました。これにより、余計な反転処理が不要になり、パフォーマンスが劇的に向上しました。

また、バッファサイズの計算において興味深いトリック(整数サイズ×3 で MAX 桁数の推定)を用いています。

#define INT_TO_STR_BUFFER_SIZE (3 * sizeof(int))

char *lwan_uint32_to_str(uint32_t value,
            char buffer[static INT_TO_STR_BUFFER_SIZE],
            size_t *len) {
    char *p = buffer + INT_TO_STR_BUFFER_SIZE - 1;

    *p = '\0';
    do {
        // 逆順に書き込み
        *--p = "0123456789"[value % 10];
    } while (value /= 10);

    size_t difference = (size_t)(p - buffer);
    *len = (size_t)(INT_TO_STR_BUFFER_SIZE - difference - 1; // 修正:元の記述の誤植を考慮

    return p;
}

4. 失敗談:ルックアップテーブルの過剰な最適化

著者は測定もせずにルックアップテーブルへ置き換え、コミットしてしまいました。

  • その結果、約 9% の高速化が得られました(しかし、後述する Facebook の手法と比べると小さな成果です)。

Facebook エンジニアリングチームの手法

Facebook チームはさらに高速な関数を公開しました。主な特徴は以下の通りです。

  • 逆順書き込みを採用(反転不要)。
  • 除算回数を半分にするための10 の桁に対するテーブルではなく、すべての桁のペア (00〜99) に対するルックアップテーブルを使用。

これにより、上記 Lwan の実装に対し約 31% の性能向上を実現しています。

size_t facebook_uint32_to_str(uint32_t value, char *dst)
{
    // 桁のペア (00-99) を文字列として定義
    static const char digits[201] =
        "0001020304050607080910111213141516171819"
        "2021222324252627282930313233343536373839"
        "4041424344454647484950515253545556575859"
        "6061626364656667686970717273747576777879"
        "8081828384858687888990919293949596979899";
    
    size_t const length = digits10(value); // 桁数取得
    size_t next = length - 1;

    // 100 を割れる場合:ペアごとのテーブル参照(除算回数の削減)
    while (value >= 100) {
        auto const i = (value % 100) * 2; // テーブルインデックスの計算
        value /= 100;
        dst[next] = digits[i + 1]; // 上位桁
        dst[next - 1] = digits[i]; // 下位桁
        next -= 2;
    }

    // 最後の 1〜2 桁の処理
    if (value < 10) {
        dst[next] = '0' + uint32_t(value);
    } else {
        auto i = uint32_t(value) * 2;
        dst[next] = digits[i + 1];
        dst[next - 1] = digits[i];
    }
    return length;
}

digits10()
と定数最適化について

関数の役割

digits10()
は整数の桁数を効率的に計算する関数です。

性能への影響と代替案

  • 呼び出しを排除できるか?
    性能を犠牲にしたくない場合は呼び出しを避ける必要がありますが、
    numeric_limits<uint32_t>::digits10
    という定数を使うことで同じインターフェースを保つことができます。
    • 理由:バッファには最大桁数を含む十分大きなサイズが用意されているため。

定数化のメリット

  • 実装上(再帰的なべき乗比較など)で定数を多用することで、小さな数字 (1〜2 桁) に対しても顕著な速度向上が見られます。
  • 著者の環境(Core i7 2640M, Arch Linux)では一貫して高速化が確認されました。

ベンチマーク結果

以下のグラフは著者が作成したベンチマークプログラムによる相対的な速度向上率です。

  • snprintf(): スポイラーですが非常に低速(グラフに表示省略)。
  • 定数値を用いた実装の方が、動的計算や関数呼び出しを避けることで安定した性能を発揮します。

(※具体的なグラフ画像は非表示)

ライセンスと参考文献の注意点

コードの利用制限

  • Facebook のコードはライセンス上の問題により、Lwan で利用できません。
  • 関連するブログ投稿にはライセンス規定が明記されていません。

2 桁ルックアップテーブルの由来

  • 2 桁のルックアップテーブル自体は、Facebook 以外の実装でも発見されています。
  • 「誰が最初にこのアイデアを思いついたのか」は不明です。

参考文献

  • 通常、同様の話題については 「Hacker's Delight」 を参照しますが、この具体的な手法については同書にも掲載されていませんでした。

同じ日のほかのニュース

一覧に戻る →

2026/10/20 6:08

Microsoft アカウントを持っていないので、RTX Spark ラップトップに Linux をインストールしようとしています

## Japanese Translation: 記事は、ASUS ProArt P16 H7607BA-SE033W において、カスタマイズされた Arch Linux ARM 環境が、NVIDIA AI ワークロードに特化して、ネイティブの Windows と同等かそれ以上(わずかに高速)のパフォーマンスを実現することを示しています。7-Zip コンプレッションや GIPS スコアなどのベンチマークタスクでは、全スレッド有効条件下において Linux は圧縮で約 5%、解压で約 3% の高速化を達成し、Windows ネイティブの結果と同等か上回る性能(例えば HP OmniBook Ultra 相当機での 157.084 GIPS vs 155.774 GIPS)を示しました。構築には、ハードウェア向けに拡張されたアップストリームの Archinstall 4.5 を用いた Arch Linux ARM が採用されており、「hid-asus」キーボードサポート、カスタムオーディオドライバー、フレームバッファマッピング用の ACPI オーバーライドなどのパッチが含まれます。ハードウェアパッケージは著者の鍵で署名され、入力はハッシュピン固定されて整合性が保証されています。システム構成では kernel 7.0.0-1022-nvidia と NVIDIA ドライバー 615.78.08、rootless Podman および CDI サポートを採用しており、統合されたメモリプールが約 116 GiB(Windows の分割領域に対し)と報告されています。表示能力としては、3840×2400 レゾリューションで 120 Hz が利用可能です。ローカル AI 推論テストでは、ARM64 コンテナ上で vLLM を用いて Qwen モデルを成功裏に実行し、混合クアンタ化および FP8 KVキャッシュを活用した効率的なモデルロード(約 68.2 GiB の重みと約 21.1 GiB の KVキャッシュを含む場合、約 16 分)および生成速度(約 30 トークン/秒)を実証しました。したがって、Linux は、強力な GPU カパビリティを得つつオープンソースの柔軟性を求めるプロフェッショナルユーザーにとって、大きな速度低下や安定性の妥協なく viable な選択肢であり、複雑な NVIDIA 構成上で先進的な AI ワークロードを展開するクリエイター向けの魅力的な代替手段を提供します。

2026/10/20 1:39

MiniMax M3.1 フラッシュ

## Japanese Translation: MiniMax が、複雑な「エージェント型(agentic)」タスク向けに設計された次世代 AI モデルの画期的な早期バージョンである M3.1 Flash を公式にローンチしました。このモデルは、AI にデジタル従業員のような形で多段階のワークフローを自律的に計画する能力を付与します。今回のリリースは、すでに匿名で 200 兆トークン以上を処理した実績に基づき、パフォーマンスとコスト効率における世代を超える飛躍を示しています。 新しいモデルは、前世代のバージョンに比べてオンライン推論速度が約3倍向上し、1秒あたり 200 トークン以上(中央値で 170 TPS 超)を生成します。また、「激しいスパース性(aggressive sparsity)」などの最適化効率技術を活用することで、エージェント型タスクのコストを 70% 削減しました。その優れた能力は、独立したベンチマークでの上位スコアにより検証されています:AutomationBench-AA ではリーディングモデルレベルのスコア、BankerToolBench(多段階計画および金融コンプライアンス)では 76.2 のスコア、DeepSWE v1.1(コード理解と機能開発)では 73.7% のスコアを達成し、OSWorld V2(61.7 スコア)と Agents' Last Exam(29.6 スコア)において中国国内のモデルの中で第 1 位にランクインしました。さらに、脆弱性の発見・検証に関する CyberGym で 82% のスコアを示すことでサイバーセキュリティ分野における強力なポテンシャルを有しており、コード監査や浸透テストでも堅牢な性能を発揮します。 MiniMax API、M Plan、および MiniMax Code を介して利用可能で、この即時ローンチは開発者と企業が、安全で自律的なソフトウェアシステムの構築に必要となる、大幅に安く高速なツールへのアクセスを提供します。完全なモデルウェイトの公開は、新しい「Pro」知的階層と併せて後日行われる予定です。フラット料金体系(1M トークンあたり)は、入力 $0.15、出力 $0.60、キャッシュ入力 $0.015 と設定されています(MiniMax-M3.1-Flash)。

2026/10/20 3:42

ロールバック操作は、士気向上まで続きます。

## Japanese Translation: PostgreSQL 19 は、ベータフェーズ開始直後に「REPACK CONCURRENTLY」を含む約 8〜10 の主要な機能を撤回しました。この変化は、ベータ期間後半に発見された重大なアーキテクチャ上の欠陥と多数のエッジケースによって引き起こされました。高度な自動化ツール(例:強化されたコードレビューやファージング)が、システムの複雑さや機能間相互作用(例:ドメインの組み合わせ、制約、パーティショニング、トリガーなど)により人手による検出が困難だった問題を浮き彫りにしました。これらの機能の多くは、現在の自動化分析機能が利用可能になる前の段階で開発されておりました。加えて、PostgreSQL 19 は 4 月から 8 月の間に「Vulnpocalypse(脆弱性の暴風)」に見舞われ、シニア開発者たちはベータウィンドウ内でのさらなるレビューやテストを優先することよりも、緊急のセキュリティ修正にリソースを割り当てることを決定しました。いくつかの問題はより長い期間の集中を必要としていた可能性がありますが、チームはリリーススケジュールを守りました。これらの機能は永久に廃棄されるものではなく、将来のリリースで洗練およびコミュニティからのフィードバックを受けた後に再導入される見込みです。PostgreSQL 20 は、未検証の主要な革新を導入するのではなく、すでにほぼ完成していたいくつかの機能を完了することに重点を置いたより慎重な戦略の下、間もなく公開を迎えています。

整数から文字列への変換(2014) | そっか~ニュース