lang_bench

Language Benchmark Analysis: Implementation Detail & Performance

このリポジトリでは、9言語・10パターンの実装を実用的な4つのタスクで比較し、言語ごとの設計や実行モデルがパフォーマンスに与える影響を分析しています。

環境・セットアップ

  • OS: macOS 16 (Darwin 25.4.0)
  • CPU: Apple M4 Pro (12-core)
  • 計測ツール: /usr/bin/time -l
  • データ生成: crystal gen_data.cr
  • 実行: crystal bench_stats.cr

1. JSON Aggregation (100MB)

1行1JSON形式のログから、特定の条件に合致するレコードを集計。パース方式とオブジェクト生成コストが性能を左右します。

  1. Swift (Unsafe) [0.328s / 38.1MB] - strstrを用いたポインタ演算による生スキャン。パースをスキップし最速。
  2. Zig [0.492s / 33.4MB] - std.jsonの静的構造体マッピングとアリーナアロケータによる最小アロケーション。
  3. Rust [0.500s / 40.0MB] - serde_jsonのゼロコピーデシリアライズによる効率的なメモリアクセス。
  4. Bun (TS) [0.592s / 207.5MB] - JavaScriptCore (C++) 内部の高度に最適化されたパサーを使用。JITの恩恵で高速。
  5. Crystal [0.958s / 66.6MB] - 動的パース(Any型)ながらLLVMの強力な最適化により1秒未満を達成。
  6. Go [1.158s / 68.6MB] - リフレクションベースのパースのため、静的マッピング言語に比べメタデータ解決のコスト大。
  7. Nim [1.648s / 49.8MB] - DOM形式のツリー構築に伴う行ごとのアロケーションがオーバーヘッド。
  8. Ruby [2.506s / 91.9MB] - C拡張パースは速いが、Rubyオブジェクト(ハッシュ)構築とインタプリタループが限界。
  9. Python [2.546s / 155.1MB] - json.loadsによる大量のdict生成と属性割り当てコストが顕著。
  10. Swift (Normal) [3.232s / 38.7MB] - Codableのリフレクションと実行時の型検証コストが極めて重い。

2. CSV Log Analysis (1GB)

巨大CSVのフィルタリングと集計。I/Oバッファリング、文字列分割、ハッシュマップの効率が鍵となります。

  1. Zig [2.034s / 108.2MB] - ゼロコピー戦略とアリーナアロケータによる圧倒的なメモリ効率と速度。
  2. Swift (Unsafe) [3.854s / 102.4MB] - fgetsとポインタ演算により、ARCや標準Stringの管理コストを完全に回避。
  3. Go [5.424s / 327.6MB] - 分割ごとのオブジェクト生成は多いが、GCとI/O層の最適化が優秀で破綻なく高速。
  4. Rust [5.790s / 149.4MB] - UTF-8検証を伴う安全な実装の中では最速。ハッシュマップの効率も高い。
  5. Nim [8.668s / 151.5MB] - ARCメモリ管理が連続的な文字列処理において効率的に機能。
  6. Bun (TS) [12.360s / 745.7MB] - Bun固有のZig実装I/Oは速いが、JSレイヤーでの文字列分割による中間オブジェクト生成でメモリが最大。
  7. Crystal [17.498s / 154.5MB] - 標準ライブラリの利便性と引き換えに、行ごとのArray生成コストが1GB規模で負荷に。
  8. Swift (Normal) [19.642s / 102.5MB] - 標準Stringの厳密なUnicode文字境界処理が、単純な分割処理において足枷。
  9. Ruby [24.778s / 194.1MB] - 大量文字列の生成と、JITなし環境でのGC回収コストが支配的。
  10. Python [33.802s / 353.5MB] - 動的オブジェクト生成と属性アクセスが1GB規模で決定的なボトルネックに。

3. Mini Grep (500MB)

特定の2キーワードをカウントする単純な文字列検索。

  1. Bun (TS) [0.596s / 84.3MB] - JavaScriptCore内のSIMD最適化検索ルーチンとJITにより、コンパイル言語を上回る。
  2. Go [0.638s / 4.4MB] - bytes.Containsによるバイトレベル比較に徹し、極めて省メモリかつ高速。
  3. Rust [0.740s / 1.9MB] - 最小クラスのメモリ使用量。堅実なI/O実装と安全性を保った最適化。
  4. Python [0.774s / 8.3MB] - in演算子の高度に最適化されたC実装(Boyer-Moore法変種)が非常に強力。
  5. Zig [0.846s / 1.5MB] - メモリ使用量は最小。標準のindexOfによる安定した検索性能。
  6. Crystal [0.984s / 2.7MB] - ネイティブコンパイルで高速だが、String抽象化層の微小なコストが上位陣に及ばず。
  7. Swift (Unsafe) [1.208s / 5.6MB] - ポインタ直接検索。現代のエンジンのSIMD最適化済みルーチンには手書きポインタ巡回では届かず。
  8. Nim [1.416s / 1.5MB] - 標準String操作における安全性チェックと境界検証が影響。
  9. Ruby [1.574s / 28.7MB] - 内部C実装だが、行の反復処理におけるインタプリタのオーバーヘッドがPythonより重い。
  10. Swift (Normal) [10.582s / 5.9MB] - Unicode文字境界を意識した厳密な検証が、単純なバイトマッチングにおいて最悪の性能差を生む。

4. LRU Cache (1M operations)

メモリアロケーションとポインタ操作が支配的なタスク。

  1. Rust [0.094s / 7.6MB] - ノードプール(Vec)とインデックス管理により、キャッシュ局所性を向上させつつ安全性を両立。
  2. Go [0.096s / 16.6MB] - 小さな固定サイズオブジェクトに特化したGCと、素直なポインタ操作の速さ。
  3. Zig [0.102s / 8.0MB] - 手動ポインタ管理とメモリアラインメントの最適化による期待通りの安定性。
  4. Crystal [0.102s / 11.8MB] - LLVMの最適化により、参照型(クラス)の操作がネイティブ級の速度まで磨かれている。
  5. Swift (Unsafe) [0.104s / 17.0MB] - ARCを完全にバイパスした手動ポインタ管理でネイティブ言語の地力を発揮。
  6. Nim [0.106s / 15.1MB] - ARCによるコンパイル時の参照管理最適化により、Rust等に迫る速度を達成。
  7. Swift (Normal) [0.132s / 18.5MB] - 通常の参照型操作。ARCのコストは存在するが、ロジックが単純であれば実用十分な性能。
  8. Bun (TS) [0.210s / 56.4MB] - JITによるMapとオブジェクト参照の最適化。スクリプト勢の中では突出した性能。
  9. Ruby [0.488s / 44.2MB] - 標準ハッシュ実装の効率の良さが、純粋なポインタ操作の遅さをカバー。
  10. Python [1.214s / 28.8MB] - __slots__等で最適化しても、純粋な属性アクセスの繰り返しが致命的な遅延に。

技術的要因の分析と総評

本ベンチマークの結果を左右した主要な技術的要因を以下の4点に集約します。

  1. メモリ管理とアロケーション戦略: ZigやRustの圧倒的な速さは、アリーナアロケータやノードプールによる「アロケーション回数の最小化」に起因します。対照的に、GC言語は微細な生成には強いものの、1GB超のデータ処理ではアロケーションコストが無視できない差となって現れます。
  2. 抽象化と安全性のオーバーヘッド: Swift (Normal)の遅延が示す通り、Unicodeの厳密な検証や型安全性のためのランタイムチェックは「安全のコスト」として明確に現れます。Unsafe版との10倍以上の差は、システムプログラミングにおいて低レイヤーへのアクセスが依然として重要であることを示唆しています。
  3. ランタイムとJITの威力: Bunは、JavaScriptCore (C++) の高速なJITコンパイルと、Zigで実装された低レイヤーなI/O・ランタイム処理の組み合わせにより、純粋なコンパイル言語を凌駕するスループットを見せました。特に、I/O層をZigが、検索処理をSIMD最適化されたC++が担当する効率的な分業が性能の鍵となっています。
  4. 実装の設計思想: RustのLRU Cacheで見られた「インデックスによるポインタ管理」のように、言語の特性(借用チェッカー等)を回避しつつキャッシュ局所性を高める工夫が、単純な言語仕様以上の差を生んでいます。

言語別サマリー

  • Zig: 手動メモリ管理の優位性を遺憾なく発揮。ゼロコピーとアリーナアロケータの組み合わせが大規模データにおいて最強の武器となる。
  • Rust: 安全性と性能のバランスが極めて高い。データ構造の工夫次第で、安全性を保ちつつZigに匹敵する、あるいは上回る効率を達成可能。
  • Swift: 標準実装(Safe)とUnsafe版で最も性能差が開いた。安全性やUnicode対応の「重さ」が顕著だが、低レイヤーに降りた際の爆発力は随一。
  • Go: 「実用的な速さ」。JSONのリフレクション等でオーバーヘッドはあるものの、GCとI/O層の洗練された最適化により、多くのタスクで安定して上位に食い込む。
  • Bun (TS): 「富豪的プログラミングの極致」。JavaScriptCore (C++) の強力なJITと、Zigによる高性能なランタイム・標準ライブラリの実装により、メモリ消費を厭わず最高速のスループットを追求する設計思想が鮮明。
  • Crystal: Rubyの書き味でネイティブの速度。標準ライブラリの抽象化コストは僅かにあるが、LLVMによる強力な最適化の恩恵が非常に大きい。
  • Nim: ARCによる効率的なメモリ管理が光る。コンパイル言語としての堅実な性能と、スクリプト言語に近い記述性のバランスが取れている。
  • Python / Ruby: 純粋なロジック処理では厳しい結果となったが、内部がC実装の標準関数を適切に選べば、特定のタスク(文字列検索等)ではコンパイル言語に肉薄できる。
Repository

lang_bench

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 0
  • about 7 hours ago
  • April 25, 2026
License

Links
Synced at

Sun, 26 Apr 2026 13:54:18 GMT

Languages