AI 時代でも C++ が Rust に勝てる理由
導入
プログラミング言語に関する議論は、エンジニアリングになるずっと前に道徳劇になることがよくあります。一方の言語はクリーンであると表現され、もう一方の言語は負担が多いと表現されます。 1つは未来として想像され、もう1つは過去からの荷物として想像されます。これらの物語は歴史をきちんと感じさせるので、感情的に満足させられます。また、期限、予算、統合の制約に加えて、10 年前には存在しなかった新たな部隊である AI コーディング アシスタントとエージェントを出荷しなければならないチームを誤解させます。
コード生成が日常業務の一部になると、問題は変わります。もはや「どの言語がエレガントか?」だけではありません。または「デフォルトではどの言語が安全ですか?」より難しく、より現実的な質問は次のとおりです。チームが AI システムに実稼働コードの作成、リファクタリング、ベンチマーク、統合、デバッグを支援することを期待している場合、それらのシステムに役立つ最も充実した環境を現在提供している言語はどれですか?私の答えは依然として C++ であり、議論の中心はノスタルジーでも男らしさでもありません。それは密度です。
C++ は依然として、Rust よりもパブリック コード、デプロイされたインフラストラクチャ、ベンダー ツール、プラットフォーム サンプル、最適化の伝承、実際の運用上の傷跡が密集した世界の中に存在しています。 AI モデルはその密度から学習します。彼らは構文を学ぶだけではありません。彼らは、人々がどのように大規模なシステムをつなぎ合わせたか、ビルドファイルがどのように進化したか、醜い統合がどのように機能するように作られたか、低レベルのバグがどのように診断されたか、パフォーマンス重視のコードが理論ではなく実際にどのように書かれていたかを学びます。これらのモデルが後で実際のエンジニアリングに役立つように求められるとき、その歴史的記憶の形状が重要になります。
これは、Rust が弱い、不真面目、無関係であるという意味ではありません。それどころか、Rust はシステムプログラミングに健全な圧力をもたらしました。これにより、メモリの安全性が無視できなくなり、多くのエンジニアリングに関する会話の調子が改善され、真に強力なツールとライブラリが作成されました。しかし、Rust の強みが存在しても、AI 支援配信における C++ の現在の利点が自動的に消えるわけではありません。成熟したエンジニアリングでは、多くの場合、両方の真実を同時に保持する必要があります。
証拠が先、スローガンは後
慎重な議論は、公的に観察できるものと推論しなければならないものを区別することから始まります。 The Stack など、コード モデルの研究で使用される公開データセットでは、Rust よりも C++ が大幅に多く表示されます。公開開発者調査と GitHub 言語トレンドでは、業界全体で C++ の絶対的な使用が広範囲に広がっていることが示され続けています。ベンダー SDK から最適化された推論ランタイム、低レベルの数学ライブラリに至るまで、パブリック AI インフラストラクチャは依然として、C および C++ で形成された世界を公開しています。 CRUST-Bench などの公開ベンチマークの取り組みは、現在のモデルが、Rust コミュニティが重視する強い意味で安全で慣用的な Rust を一貫して生成するのに依然として苦労していることを示唆しています。
これらの事実から、私たちは独断ではなく推論を行います。現在、AI システムは、C++ を取り巻く環境が充実しているため、多くのシステム領域で実稼働に役立ち、統合可能で最適化可能な C++ を生成する可能性が高いと推測されます。これは魔法ではありません。それはフィードバックと組み合わせた露出です。より多くのリポジトリ、より多くのビルド スクリプト、より多くのハードウェア関連のサンプル、より多くのベンダー統合、より多くの公開バグ修正、より多くのパフォーマンス調査、より多くの実稼働戦争のストーリーを備えた言語は、人間のエンジニアが修正を開始する前にモデルをほぼ正確にするためのより多くの方法を提供します。
この点は、新しい言語にとって不親切に聞こえるため、しばしば反対されます。しかし、Rust が公共土砂を蓄積する時間が減ったと言っても、それは Rust を侮辱するものではない。 C++ は何十年にもわたって、オペレーティング システム、ブラウザー、データベース、メディア スタック、セキュリティ ツール、ゲーム エンジン、通信、科学技術コンピューティング、組み込み製品、金融システムに組み込まれてきました。さびは急速かつ見事に成長しましたが、成長は地質学的深さとは同じではありません。 AI モデルは深さを吸収します。
コーパスのサイズが人々が認める以上に重要である理由
エンジニアは、トレーニング データの量を、あたかも粗末な論点であるかのように扱うことがあります。実際には、それはもっと人間的な意味で重要です。実稼働コードベースで動作する AI エージェントは、通常、第一原理から完璧なアルゴリズムを発明することはありません。もっと厄介なことをやっているのです。それは、CMake ファイルの更新、1 つのプラットフォームでのコンパイラの不満への適応、ホットパス コンテナの置き換え、ベンダー API のラップ、イメージまたはテンソル レイアウトの変換、ABI の不一致の修正、または周囲のすべてを壊すことなく古いネイティブ サブシステムの負担をわずかに軽減することなどです。
これらのタスクは、通常の不完全な生きたコードに精通することに報酬を与えます。このエージェントは、きれいな教科書の例だけでなく、隣接する問題を解決するための何千もの実際の試みを見てきたことから恩恵を受けています。 C++ は、モデルにそのマテリアルをはるかに多く提供します。より現代的な C++ 、徐々に修復されつつあるレガシー C++ 、よりベンチマーク主導型の C++ 、依然として何らかの形で重要なビジネスを運営しているより恥ずかしい C++ 、そして実際のシステムが要求する種類の妥協を正確に乗り越えている人々の例がさらに増えています。
これが、「乱雑な運用 C++」が依然として貴重なトレーニング データである理由です。エンジニアの中には、この言葉を聞いて、それが訴訟を弱めるのではないかと想像する人もいます。実際にはそれが強化されます。実稼働システムは、完全にエレガントなグリーンフィールド モジュールで構成されているわけではありません。これらには、レガシー インターフェイス、奇妙な ABI の仮定、プラットフォームの条件、ハードウェアの癖、部分的な移行、そして美しくなる前に便利だったために生き残ったコードが含まれます。 AI システムが C++ でそのような状況の例をさらに多く見てきた場合、そのような状況内で役立つ準備が整っているだけです。
反例は公然と述べる価値がある。チームが強力な Rust の専門知識、明確な安全要件、適度な統合ニーズを備えた小規模なグリーンフィールド サービスを構築しており、周囲に重いネイティブ エコシステムが存在しない場合は、Rust の方がローカルな選択肢となる可能性があります。その状況では、周囲のエンジニアリングコンテキストがより単純であり、人間のチームがシステムをより狭い範囲の複雑さの範囲内に保つことができるため、コーパスサイズからの議論はそれほど決定的ではありません。重要なのは、C++ がすべての引数に勝つということではありません。重要なのは、問題が古くなり、より奇妙で、よりパフォーマンスに敏感になり、既存のネイティブ インフラストラクチャとより絡み合うにつれて、C++ が AI システムにとって効果的に支援しやすい言語になるということです。
AI インフラストラクチャの世界は依然として C++ の形をしている
たとえトレーニング データの量を完全に無視したとしても、デフォルトを C++ に引き寄せる第 2 の力が依然として存在するでしょう。それは、最新の AI 製品の基盤となるインフラストラクチャが強力にネイティブのままであるということです。 CUDA、最適化された数学ライブラリ、ONNX ランタイム内部、oneDNN、OpenVINO、トークナイザー実装、マルチメディア前処理パイプライン、モデル サービング アクセラレータ、ハードウェア ベンダー SDK、および多くの展開ランタイムは、C または C++ で記述されているか、最も重要なインターフェイスを C または C++ で公開しています。これは、Rust がそれらを呼び出すことができないという意味ではありません。つまり、ランドスケープ内の最短パスは依然として通常は C または C++ パスであるということです。
AI コーディング エージェントは単体では役に立たないため、これは重要です。これらは依存関係グラフ内で役立ちます。ランタイムの統合、ビルドのデバッグ、ホット パスの調整、またはベンダー SDK の境界を越えた所有権についての理由付けを支援するように求められるモデルは、同じ言語ファミリーで隣接するサンプルを多数確認した場合に有利になります。 C++ は、パフォーマンスが重要な AI インフラストラクチャ作業のほとんどにおいて、Rust よりもその環境への馴染みの恩恵を依然として受けています。
ここでは、フィードバック ループに関する会話が重要になります。 AI が生成したコードは、人間が迅速に検証できる場合にのみ真の価値を発揮します。ベンチマーク、プロファイリング、リプレイ、サニタイザー、ハードウェア カウンター、および低レベルの診断に関するエコシステムが非常に成熟しているため、C++ を使用すると、これらのドメインでより充実したローカル検証がチームに提供されることがよくあります。エージェントが C++ 推論パスの変更を提案すると、チームは多くの場合、それをコンパイルし、プロファイリングし、割り当て動作を検査し、レイテンシの分布を比較し、迅速に反復することができます。 Rust にも確かに強力なツールがありますが、AI に隣接する多くのネイティブ システムでは、ライブラリ、サンプル、プロファイラー、および既存のプラクティスの密度を組み合わせることで、依然として C++ が緊密な人間参加型の修正ループを実行しやすくなっています。
Rust の方がきれいに見えても、チームは C++ を使用したほうが速く動ける理由
これは、清潔さに対して失礼に聞こえるため、イデオロギーを傷つける傾向がある点です。ホワイトボード上では錆がきれいに見えることがよくあります。所有権は明示的です。コンパイラは重要な間違いを防ぎます。正しさを重んじる文化は素晴らしいです。しかし、制作速度と言語の優雅さは同じではありません。実際の配信速度は、既存のコードベース、利用可能なライブラリ、人材プール、デバッグ ツール、デプロイメントの制約、AI 支援の品質、来月さらに 1 つ変更を加えるコストなど、ループ全体から現れます。
現在、C++ は、チームが言語を離れることなく、周囲の世界についてより多くのことを尋ねることができるため、多くの AI 時代のシステムでその広範なループに勝ち取っています。古いネイティブ ライブラリを統合し、ネイティブ パフォーマンス作業を念頭に置いて構築されたプロファイラーを接続し、アロケーターを調整し、プラットフォーム固有の機能を利用し、何か問題が発生した場合には、はるかに多くの公開サンプルから抽出することができます。 AI アシスタントもまったく同じ現実から恩恵を受けます。モデルの周囲の世界が密集していてよく移動すると、モデルのラフ ドラフトはより速く改善されます。
2 つのチームが、カスタムの前処理、複雑なデプロイメント マトリックス、および繰り返しのパフォーマンス チューニングの必要性を伴う、遅延に敏感な推論サービスを構築していると想像してください。 Rust チームは、メモリ安全性に関する小規模なバグを生成する可能性がありますが、それは簡単ではありません。しかし、C++ チームがエコシステムをより直接的に統合し、実際のコードベースでより強力な AI の提案を取得し、成熟したネイティブ ツールを使用してパフォーマンスの変化をより迅速に検証できれば、全体的な配信結果は依然として C++ に有利になる可能性があります。ビジネスの観点から言えば、オンラインでの哲学的な議論で 1 つの言語が勝てるかどうかよりも重要です。
有用な反例は私たちを正直に保ちます。プロジェクトの主要なリスクが統合やパフォーマンスの進化ではなく、比較的単純な依存関係を持つ新しいサービスのメモリの安全性である場合、Rust は組織的により良い結果を確実に生み出すことができます。間違いは、その真実を受け入れて、それを AI に隣接するあらゆるシステムの問題に無差別にエクスポートすることです。言語は説教ではなく文脈で勝利します。
Rust が今でも正しくできること
Rust は尊敬に値しますが、C++ が Rust を風刺すると主張は弱くなります。 Rust は、安全でない仮定を可視化することに優れています。それは所有権と生涯に関して強い規律を生み出します。多くの場合、既存のネイティブ世界との互換性よりも正確性と保守性が優先されるグリーンフィールド インフラストラクチャにとって、これは魅力的な選択となります。一部のチームでは、コードベース自体がある種のエンジニアリングの真剣さが強制されるため、Rust によって採用の明確性も向上します。
また、C++ が古いからといって、デフォルトで C++ が勝てるわけではない、ということを明確に言うことも重要です。規律のない C++ は依然として危険です。チームに弱いレビュー文化があり、プロファイリングの習慣がなく、テストが不十分で、可観測性が尊重されていない場合、コーパスが大きくなり、ツールが充実してもチームを救うことはできません。 AI システムは、優れたエンジニアリングを加速するのと同じくらい簡単に、その混乱を増幅させる可能性があります。本当の主張はより狭く、より現実的です。規律あるチームがパフォーマンスに敏感で統合が重視される AI 時代のシステムの問題を解決していることを考えると、エージェント、ツール、エコシステムの重力がすべてそれを強化しているため、今日でも C++ がより強力なデフォルトの選択肢です。
これが、私がユニバーサルウィナーではなくデフォルトベットという表現を好む理由です。デフォルトの賭けは、立証責任がまだ他の場所に移っていないときに選択するものです。 Rust は特定のプロジェクトでその変化を得ることができます。しかし、C++ は、作業がネイティブ AI インフラストラクチャ、低レベルのパフォーマンス、長寿命の実稼働システム、または AI エージェントが大量に公開されている種類のコードベースと深く絡み合っている場合は常に、C++ に有利なより多くの証拠から開始します。
現実的な決定方法
ホット パスがネイティブで、依存関係グラフがネイティブで、プロファイリングのストーリーが重要で、AI アシスタントが煩雑な実際の運用コード内で役立つことを期待している場合、C++ について最初の真剣な言語の議論を行う価値があります。システムがグリーンフィールドであり、安全性が優先され、周囲のエコシステムがすでに Rust の形をしており、問題が古いネイティブ層に大きく依存していない場合、Rust はより魅力的になります。システムに両方の世界が含まれている場合 (多くの場合そうである)、成熟した答えは部族的な純粋さではなく、ハイブリッド アーキテクチャであることがよくあります。
このフレームワークは、アイデンティティではなく仕事への決定を戻すため、会話を落ち着かせます。既存の C++ プラットフォーム内のネイティブ推論ランタイムは、新しいコントロール プレーン サービスと同じ問題ではありません。低レイテンシーのメディア パイプラインは、バックエンド API と同じ問題ではありません。モデルを提供するエッジ コンポーネントは、チェーン ネイティブの状態遷移エンジンと同じ問題ではありません。実際の作品に名前を付けると、通常、言語の選択はイデオロギー的ではなくなり、より明白に見えます。
このように決定を下すことには人間にとっての利点もあります。どの言語が賞賛に値するかを考えるのをやめ、現在のシステムが信頼性があり、理解しやすく、改善可能になる最も可能性が高いのはどの言語であるかを問い始めると、チームはより協力的になります。 AI による支援により、これはさらに重要になります。エージェントは、合成された自信で言語ファンダムを飾るために使用される場合ではなく、検証の文化に組み込まれている場合に強力です。
本当のチャンス
AI 時代における大きなチャンスは、単にエージェントがコードを書けるようになるというだけではありません。それは、古いコードを読み、編集を提案し、ベンチマークを改善し、プロファイラーの手がかりを明らかにし、大まかなアイデアをコンパイル可能な実験に変換し、エンジニアが以前よりも早く疑いから測定に移行できるようにするなど、成熟したシステムのフィードバック ループ全体に参加できるようになったということです。その世界では、最も利益を得る言語が、必ずしも最も優れた理論的ストーリーを持つ言語であるとは限りません。それは、公的で実用的で、実戦を経験した現実が最も厚い網の目で結ばれているものです。
現在でも、重大なシステム問題の大部分に対して、その言語は C++ です。これは良いニュースです。業界が Rust から学ぶのをやめるべきだからではなく、チームが既存のネイティブ知識の膨大な量を、AI が登場した瞬間に消え去ったふりをするのではなく利用できるからです。最も生産的な姿勢は勝利主義ではありません。それは感謝です。 C++ は数十年にわたる実際のエンジニアリング メモリを蓄積しており、AI システムはそのメモリを使いやすくしています。賢明なチームはそれを活用するでしょう。
ハンズオン ラボ: ネイティブ スコアリング パイプラインを構築および改善する
AI 時代の言語選択に関する記事にコードが含まれていない場合、説教になる危険があります。
そこで、実際の企業で AI エージェントが常に改善を求められているような、小さなネイティブ C++ ユーティリティを構築しましょう。これは、データをロードし、単純な特徴を計算し、結果を並べ替え、上位行を出力するテキスト スコアリング パイプラインです。
わざと控えめにしています。ほとんどの生産エンジニアリングは控えめです。
__コード_0__
#include <algorithm>
#include <chrono>
#include <cctype>
#include <fstream>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
struct Sample {
std::string text;
double score = 0.0;
};
static int count_digits(std::string_view s) {
int n = 0;
for (unsigned char c : s) {
n += std::isdigit(c) ? 1 : 0;
}
return n;
}
static int count_upper(std::string_view s) {
int n = 0;
for (unsigned char c : s) {
n += std::isupper(c) ? 1 : 0;
}
return n;
}
static int count_punct(std::string_view s) {
int n = 0;
for (unsigned char c : s) {
n += std::ispunct(c) ? 1 : 0;
}
return n;
}
static double score_line(std::string_view s) {
const auto len = static_cast<double>(s.size());
const auto digits = static_cast<double>(count_digits(s));
const auto upper = static_cast<double>(count_upper(s));
const auto punct = static_cast<double>(count_punct(s));
return len * 0.03 + digits * 0.7 + upper * 0.15 - punct * 0.05;
}
int main(int argc, char** argv) {
if (argc < 2) {
std::cerr << "usage: scorer <input-file>\n";
return 1;
}
std::ifstream in(argv[1]);
if (!in) {
std::cerr << "cannot open input file\n";
return 1;
}
std::vector<Sample> rows;
rows.reserve(200000);
std::string line;
while (std::getline(in, line)) {
rows.push_back({line, 0.0});
}
const auto t0 = std::chrono::steady_clock::now();
for (auto& row : rows) {
row.score = score_line(row.text);
}
std::sort(rows.begin(), rows.end(), [](const Sample& a, const Sample& b) {
return a.score > b.score;
});
const auto t1 = std::chrono::steady_clock::now();
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count();
std::cout << "processed " << rows.size() << " rows in " << ms << " ms\n";
const size_t limit = std::min<size_t>(5, rows.size());
for (size_t i = 0; i < limit; ++i) {
std::cout << rows[i].score << " | " << rows[i].text << "\n";
}
}
建てる
Linux または macOS の場合:
g++ -O2 -std=c++20 -o scorer main.cpp
./scorer sample.txt
MSVC を使用する Windows の場合:
cl /O2 /std:c++20 main.cpp
.\main.exe sample.txt
この小さなプログラムがなぜ役立つのか
それはまさに、AI 支援エンジニアリングが具体化される種類のコードだからです。
- それはネイティブです
- 文字列と記憶に触れます
- 測定可能なランタイムを持っています
- それはプロファイリングすることができます
- 段階的に改善できる
それが今日の多くの C++ エージェントの本当の生息地です。大掛かりなデモンストレーションではなく、再発明することなく改善する必要がある通常のネイティブ プログラムです。
愛好家向けのテストタスク
この記事を実践的な演習にしたい場合は、次のことを試してください。
- お気に入りのコーディング エージェントに依頼して、出力を変更せずにプログラムを最適化してもらいます。重複したパスや不要な一時的なパスが削減されているかどうかを検査します。
- ファイルのロード、スコアリング、並べ替えに個別のタイミングを追加します。実際に時間がどこに行くのかを確認してください。
- 入力を 100 万行に置き換え、さまざまなエージェントによって提案された最適化の品質を比較します。
- ユーティリティを Rust に移植し、エクスペリエンスを正直に比較します。 何がよりクリアに感じられ、何がより重く感じられ、そしてどの周囲のツールがこの正確なタスクに対してより成熟していると感じられるのか。
- プロファイラーで C++ バージョンを実行し、ホットスポットに関する最初の推測が実際に正しかったかどうかを書き留めます。
これは小さな演習ですが、だからこそ役立つのです。エンジニアリングに関する議論のほとんどは、実際の小規模なプログラムとの接触を強いられると、より真実味を帯びてきます。
まとめ
Rust は尊敬に値します。これにより、安全に関する会話の基準が向上し、システム プログラミングにより健全なデフォルトのセットが提供されました。しかし、AI 時代は債務不履行だけが報われるわけではありません。これは、実際のコードの最大の生きたコーパスの中心に位置する言語、低レベル統合の最も深いエコシステム、最も豊かな最適化文化、そして生成されたドラフトから測定可能な運用結果までの最速の実用的なループに報いるものです。現在でも、これは Rust よりも C++ をより強く表現しています。
だからといって C++ が道徳的に優れているというわけではありませんし、Rust が無関係であるというわけでもありません。これは単に、ネイティブ システムの多くの深刻な問題に対して、ターゲットの世界が C++ である場合でも、AI エージェントの足元にはまだより有用な基盤があることを意味します。これを理解しているチームは、ドラマチックなことをせずに、より良い意思決定を下すことができます。彼らは、Rust が最も強いところは Rust から学び、メモリが最も経済的に価値があるところには C++ の膨大な蓄積メモリを使用することができます。
参考文献
- GitHub Octoverse 2024: https://github.blog/news-insights/octoverse/octoverse-2024/
- GitHub Octoverse 2025: https://github.blog/news-insights/octoverse/octoverse-a-new-developer-joins-github-every-second-as-ai-leads-typescript-to-1/
- スタック オーバーフロー開発者アンケート 2023: https://survey.stackoverflow.co/2023
- Stack Overflow Developer Survey 2025 テクノロジー セクション: https://survey.stackoverflow.co/2025/technology/
- スタック データセット カード: https://huggingface.co/datasets/bigcode/the-stack
- スタックペーパー: https://arxiv.org/abs/2211.15533
- 事前トレーニングにおけるコード データの影響に関する ICLR 2025 論文: https://openreview.net/pdf?id=zSfeN1uAcx
- CRUST-Bench: C からsafe-Rust へのトランスパイルのための包括的なベンチマーク: https://arxiv.org/abs/2504.15254
- CUDA C++ プログラミング ガイド: https://docs.nvidia.com/cuda/cuda-c-programming-guide/
- ONNX ランタイム C/C++ API: https://onnxruntime.ai/docs/api/c/index.html
- PyTorch C++ フロントエンドのドキュメント: https://docs.pytorch.org/cppdocs/frontend.html
- C++ コア ガイドライン: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines