超高速なコンパイル、GC、並列プリミティブ

グーグル、C/C++に代わる新言語「Go」をOSSで公開

2009/11/11

 グーグルは2009年11月10日、Cのようにシステム記述に適したプログラミング言語「Go」をBSDライセンスの下に公開した。C++のようなC言語の拡張ではないが、Cに似た構文が特徴で、ガベージコレクタ(GC)や並列プリミティブ、イテレータ、実行時リフレクションなどを備えた新しい設計が目を引く。Goはグーグルの社員7人が「20%の自由時間」を利用して開発した。設計・実装を行っているのが分散OS「Plan 9」の創案者であるロブ・パイク氏や、Unix、Cの生みの親、ケン・トンプソン氏、Google ChromeのV8エンジンを開発したロバート・グリースナー氏など錚々(そうそう)たるメンバーで、こうした点でも注目を集めそうだ。

pike.jpg Goについて説明するグーグルのロブ・パイク(Rob Pike)氏。Unix、C、Plan 9の共同開発者としても知られている
sample.jpg Goのコードサンプル。ブレースによるブロックなど見た目はCと大きく変わらないが、実際にはかなりアグレッシブな取り組みだ
web.png Goのオフィシャルページ。左上の微妙なキャラがPlan 9を彷彿させる

 グーグル社内では、まだGoを使っていないが、今後はWebサーバなどのシステム関連のソフトウェアで実用を検討しているという(GoのオフィシャルサイトはGoで書かれたWebサーバを使っている)。パイク氏は、Goはシステム記述向けを念頭に設計されているが、フロント・エンドのソフトウェアでも生産効率の高いプログラミングができるだろうとしている。

数十万行を数秒で高速ビルド

 10月30日に行った講演(動画)の中でロブ・パイク氏は、現在のシステム記述言語が抱える問題を指摘している。膨大なライブラリが当たり前になり、依存関係も複雑になった結果、ソフトウェアのビルドに「耐え難いほど時間がかかるようになってしまった」(パイク氏)。Goではコンパイルやリンクにかかる時間を劇的に短縮。3000行のライブラリが200ミリ秒、正規表現やGC、並列処理、RPC、数学関連などを含むGoの標準ライブラリ全体(12万行程度)でも9秒でmakeが終了するという速さだ。数秒のコンパイル時間でも、Goに慣れてしまったパイク氏にとって「非常に長く感じられる」という。

 ビルド時間が長くなったことに加えて、現在のC/C++ではネットワーク、クラスタ、マルチコアなど多くの技術変化に十分にキャッチアップできていないという。「もう長らくシステム言語が登場していない」(パイク氏)。

 Goは、まだ実験段階だが32ビット、64ビットのx86アーキテクチャ向け、およびARM向けのコンパイラと、GCC向けのフロントエンドが動いており、実行速度は「ケースによるがCの10〜20%遅い程度。GCがある言語としては十分」(パイク氏)とパフォーマンスも出ているようだ。仕様書のほか、Javaで言うJavadocのようなGodoc、チュートリアル、イディオム集(Effective Go)など多くのドキュメントが公開時点で整備されているほか、コーディングスタイルを統一するフォーマッタも提供するなど、Goはコンセプト・プルーフや研究目的の言語としてではなく、強く実用を想定した言語であるようだ。

 Goの設計を始めたのは2007年暮れで、2008年には動くものができていたという。

ポインタ演算の排除、GCの導入

 生産性の上でC言語が抱えている問題は、ガベージコレクタがなくメモリ管理がプログラマに任されていること、ポインタや配列の仕様が混乱を招きがちなことの2つが大きい。JavaやC#の成功は、これらの課題を解決したことによるところが大きい。

 同様にGoでは、アドレスを扱うポインタそのものは参照渡しのために存在しているが、Cのようなポインタ演算がなく、事実上ポインタを排除している。変数宣言でも混乱がないように「var a, b *int;」のように型宣言を変数名の後ろにもって来ている。

 ポインタ演算による配列アクセスはできないが、Goでは配列や文字列に対して部分列を切り出せる“スライス”が使える。スライスは配列へのポインタとサイズ、最大サイズの3つの基本データを持った構造体のようなもので、スライス経由で配列の読み書きができるという。

 GCの採用は大きな一歩だ。「t1 := new(T);」と書けば、t1という変数宣言とオブジェクトの生成ができ、明示的なメモリの解放は不要だ。現在のGoの実装ではマーク・アンド・スイープ方式の素朴なものであるものの、今後はIBMが開発した遅延のない並列GCを入れる予定で、パイク氏は、これまでの経験から実装可能だと見ているという。

 Goは軽量な型システムを備えた静的型付け言語という。型の暗黙変換はない。近年、静的型付け言語で記述が冗長になりがちなことなどから、動的型付け言語の人気が高まっているが、それは多くの静的型付けの実装が悪かったからだ、とパイク氏は指摘する。

JavaやC++よりもオブジェクト指向的

 Goにはクラスや継承といった概念はないが、「GoはJavaやC++よりも、ずっとオブジェクト指向的な言語だ」(パイク氏)という。実際、ドット記法によるメソッドの呼び出しに似た文法で、特定の型に紐付いた関数を呼ぶことができる。

 Goには“インターフェイス”と名付けられた仕組みがあり、パイク氏自身は「おそらくGoの中で、もっとも斬新なアイデア」だとしている。Goのインターフェイスは、C++でいえば、純粋仮想関数に似ているという。データメンバがなく、すべての関数が仮想関数であるようなクラスだ。Goでは、あるインターフェイスが定義するメソッドをすべて実装した型は、そのインターフェイスを実装しているものと見なされる。こうして個々のメソッドという実装をクラスという概念でまとめるよりも、より柔軟な型とメソッドの対応付けが可能になるのだという。

独自の並列処理の抽象化

 Goで注目すべきなのは、並列処理を念頭に設計されていることだ。Goではmutexやロックといった機構のほかに、抽象度の高い“ゴールーチン”(Goroutines)や“チャンネル”(Channels)といった仕組みを備えている。

 Go文は関数名を指定することで新規にゴールーチンのスレッドを生成する。ゴールーチンのスレッドは、実際にはOSネイティブの複数スレッドに自動的に割り振られ、コルーチンのように動いているが、プログラマは実装の詳細を気にしなくていいという。Goによって生成されたスレッドはアドレス空間を共有しているが、データの受け渡しなどには“チャンネル”が使える。例えば重たい計算処理をあるスレッドで行い、その結果をチャンネル経由で受け渡すことができる。ゴールーチンは、送受信を全二重で行うサーバの実装のような例でコードがシンプルになるほか、例えば素数列の生成といった処理では、自然数の生成を1つのゴールーチンで行い、それをチャンネル経由で受け取ったフィルタ関数で処理するといった分散処理の流れを書きやすいのだという。

Cっぽくて違和感なし、Cの面倒さなし

 Goは表面上はCのように見えるが、スクラッチからやり直したC++とも言えるプログラミング言語だ。独自の型システムや並列処理のプリミティブなど、かなりラディカルにCとは異なっている。一方、そのジョークのような名前に反して、すでに基本的なライブラリが存在しており、UTF-8対応の正規表現ライブラリも存在するなど、実用を強く指向している。

 Goが実用段階に入るにはまだ時間がかかりそうだが、C/C++の代替となり得るのか、さらにはC++、Java、C#、Objective-Cに並ぶCの後継言語となれるのか、注目株と言えそうだ。

(@IT 西村賢)

情報をお寄せください:

Coding Edge フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

キャリアアップ

- PR -

注目のテーマ

ソリューションFLASH

「ITmedia マーケティング」新着記事

天候と位置情報を活用 ルグランとジオロジックが新たな広告サービスを共同開発
ルグランとジオロジックが新たな「天気連動型広告」を共同開発した。ルグランが気象デー...

“AI美女”を広告に起用しない ユニリーバ「Dove」はなぜそう決めたのか
Unilever傘下の美容ケアブランド「Dove」は、「Real Beauty」の20周年を機に、生成AIツー...

有料動画サービス 34歳以下では過半数が利用経験、4割は1日1回以上利用
「ニールセン・ビデオコンテンツ アンド アド レポート 2024」を基に、テレビ画面での動...