The Daily Newsstand · Free, Always
Monday, October 26, 2026

C++やRustよりも高速に動作しメモリ使用量も少ないプログラミング言語「Goose」

Translate

GooseはAIの支援を受けて開発された革新的なシステムプログラミング言語です。「メモリ安全性」「驚異的な実行速度」「コンパクトなメモリ使用量」を両立させることに成功しており、既存のC++やRustといった言語をベンチマークで凌駕する可能性があります。

The Goose Programming Language · Goose
https://aardappel.github.io/goose/

GitHub - aardappel/goose: The Goose Programming Language · GitHub
https://github.com/aardappel/goose

Gooseは設計思想と機能セットにおいて、既存のプログラミング言語とは一線を画しています。

・C++やRustより高速かつメモリ安全
16のベンチマークを通じ、Gooseは汎用的なC++の3.3倍・手動で最適化されたC++の1.16倍・Rustの1.12倍の速度で動作し、メモリ使用量はそれぞれ1.9 倍・1.3 倍・1.2 倍の効率化が確認されています。

・アロケーター・ガベージコレクション・参照カウント・デストラクタが不要
100万個の子要素を持つ構造体を解放する場合、ネストがどれほど深くても1回のストア操作で完了できます。

・配列の拡張時も参照は保持される
拡張中の配列への参照は、Gooseでは型付き参照を維持しますが、同様の実装を行うにはC++では「reserve」を呼び出して最大数分のメモリを確保する必要があり、Rustでは配列のインデックスを使用する必要があります。

・ゼロアノテーションによるメモリセーフ
コンパイラはすべての参照のルートとなるオブジェクトを推論し、所有オブジェクトよりも長く存続する可能性のある参照を拒否するため、メモリセーフが担保されます。

・ネストしたデータをインラインで保持
文字列・文字列の配列・可変長フィールドを持つレコード・レコードの配列をポインタを含まない1つの連続ブロックとして格納します。例えば、C++では160バイトを消費し1回の割り当てを必要とするレコードであっても、Gooseでは29バイトで済みメモリ割り当ても不要です。

・可変サイズの列挙型
可変サイズの抽象データ型は各値を最大サイズではなく個々のバリアント自身のサイズで格納するため、Rustの列挙型に比べてメモリ使用量は1/4で済みかつ実行速度は2倍となります。

・相対参照による位置独立性
型付けされチェックされたリンクを1~4バイトのオフセットとして格納する相対参照により、データ構造は位置独立となるため、ファイルへの書き込み・読み込みが容易になります。

・インプレース構築
呼び出しの深さに関わらず、データは最終的な位置に直接構築されるため、「items.push(parse(line))」のような操作で解析されたレコードが直接配列中に書き込まれます。

・効率的なエラーハンドリング
「return err from load」のような構文がサポートされており、使用すると数スタックの任意のフレームまで、静的にチェックされアンワインダーやResult型や「?」を必要としない方法でエラーを伝播させることができます。

・共有メモリのないスレッド
各ワーカーは独立したメモリ空間を持つ別個のプログラムとしてコンパイルされ、値は型付きキューとmemcpyを介してスレッド間で安全に受け渡されるため、データ競合・ロック・アトミック操作・メモリ順序といった概念は言語レベルで存在しません。

・オーバーヘッドのないジェネリクス・高階関数
ジェネリクスや関数値はコンパイル時のエンティティとして扱われ実行時のオーバーヘッドなしで機能しするため、「xs.filter() { it > 0 }」のようなコードはループ構文と同等のパフォーマンスを発揮します。

・C言語へのコンパイルとC関数の直接呼び出し
Gooseのソースコードは単一のCファイルにコンパイルされるため、Cコンパイラが存在する環境であればどこでも実行可能であり、「extern fn」構文によりC関数を直接呼び出すことも可能です。

Gooseの高いパフォーマンスはメモリモデルに起因します。そのうちの1つが「スコープ終了時にデータスタックが解放される」ということです。プログラムは、ネイティブコールスタック・静的データ・N個のデータスタックを持ち、Nの値はコンパイラによって計算されます。データスタックは次に割り当てるべき空きメモリの先頭アドレスを指し示す「バンプポインタ」を持つ大きなアドレス空間が予約されたものです。各スタックには最大で1つのサイズ変更可能な値が存在し、常に最上位に配置されます。必要なメモリ容量はすべてコンパイル時に証明され、ランタイムはバンプポインタのみを追跡するため、スタックの拡張によってデータが移動したり容量がチェックされたりすることはありません。そしてスコープ終了時にデータスタックは解放されます。

Gooseのpush()は新しい要素への参照を返すため、プログラムは配列を構築しながら要素をリンクでき、配列のメモリは決して移動しません。 C++のvectorやRustのVecはメモリの再割り当てが発生する可能性があるため、配列のメモリが不動である保証はありません。Gooseのこの性質はいくつかのベンチマークでのパフォーマンス向上に貢献しています。

struct Item { id: i32, weight: f32 }

var items: Item[>..] = [];
let first .= items.push(Item { 1, 0.5 });             // 0番目要素への参照
for i: i32 in 2..1000001 { items.push(Item { i, 0.0 }); }
first.weight = 99.5;                                  // 100万回push()した後でも参照は有効

Gooseコンパイラをビルドするには、git・cmake・Cコンパイラが必要です。

git clone https://github.com/aardappel/goose
cd goose
cmake -B build -DCMAKE_BUILD_TYPE=Release -DGOOSE_BUILTIN_LIBS=all
cmake --build build --config Release

記事作成時点における制限事項は以下の通りです。

・データの保存場所、つまり誰が所有し有効期間がどれくらいかを考慮する必要があります。
・再帰関数は、再帰呼び出しをまたいで拡張可能なデータを保持することはできません。
・可変サイズの要素の配列は反復処理は可能ですがインデックスによる参照はできません(参照のインデックスを別途保持している場合を除く)。
・エスケープクロージャ・関数ポインタ・ADTタグを超える動的ディスパッチは存在せず、プログラム全体のコンパイルのみがサポートされています。
・reusableプールに戻されたにもかかわらず参照され続けているスロットは、次の所有者がそこに書き込んだ内容を読み取れます。これは論理バグですがメモリ破損は決して起こりません。

Gooseは人間による言語設計に基づきながらも、ほぼ完全にAIによって作成されました。長らく設計は完了していたが実装する時間を取れなかったものの、特にFableが登場したことによりGooseの実装が現実味を帯びたそうです。開発者はAIが既存言語の再現にとどまらず、全く新しい言語を実装できるかという実験としてこのプロジェクトを推進したとのことです。

View the original on GIGAZINE →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.