[ruby][lightweight language]動的言語と静的言語の処理速度は変わらない?

これまた引っ張りだしてきたネタですが、みんな信じきってしまっている気配がするのでWebの隅っこにでもちゃんと書いておきます。

id:yukobaさんのJavaScriptRubyより速い理由とされた記事の中で、「Goslingさん曰く、変数などに型があるかどうかは処理系のパフォーマンスにあまり影響しない」といったらしいと聞いたので、本当かどうか読んでみました。

Goslingさん曰く

これがGoslingさんの記事です。
http://blogs.sun.com/jag/entry/scripting_flamewar

おそらく該当個所はこの辺だと思います。

Raw execution performance: One of the usual arguments for scripting languages having acceptable performance is that the overhead of interpretation and dynamic typing doesn't matter. The performance of the system is dominated by other factors: typically IO and the language primitives. For example, PERL apps usually spend the majority of their time in file IO and string primitives. I've strongly made this argument in the past, and it's quite valid.

意訳してみるとこんな感じでしょうか。めちゃくちゃ省略していますが。

パフォーマンス:
動的スクリプト言語を推す人は、こう言います。
インタプリタだと実行が遅い」と言われるけど、ほとんどの場合、ボトルネックはファイルIO処理のディスク待ち時間と、
(インタプリタ実行部分ではなくて)処理系に用意されたprimitive(ここでのprimitiveは処理系内部の組み込み処理の意味)部分になっているので、実際のところあんまり関係ない。

要は、変数の型がないと遅いけど、特定の用途ではスクリプト言語のオーバーヘッドは目立たないということです。
#しかも、元記事では「とは言うものの、やっぱりみんな使い方を誤って遅くなるんだよ。」とひっくり返されている意見ですが・・・

動的言語はなぜ遅くならないか

元記事ではさらっとやり過ごしていますが、もうちょっと噛み砕いて言うと、


(a) インタプリタ部分 : 当然遅い

(b) 動的言語の部分  : どうしても実行時に型を特定するから遅くなる

(c) 各種処理内容自体 : 処理系内部で実装された専用処理(primitive)であれば速い

という事実があるけれども、実際のスクリプトでは(a)(b)の処理時間より(c)の時間の方が圧倒的に多くなるような処理ばかりだから、実用上は(a)(b)の時間は(c)に隠されて見えなくなるよ、と言うことです。
文字列の正規表現とかだと、「インタプリタ処理の時間」「正規表現のルーチンを開始するまでのディスパッチ処理時間」よりは「(C言語のルーチンで)実際にマッチングをかけている処理の時間」の方が圧倒的に長くなります。

プリミティブ型は速くなるのか?

上の記事を見る限り、「言語仕様にプリミティブ型があれば動的言語でも速くなる」というようなことは言われていません。
JavaScriptだろうがRubyだろうが上記の(a)〜(c)はすべて等しく当てはまるので、この理由を元にJavaScriptRubyより速いということは断言できません。

注意しなければならないのは「primitive」の意味だと思います。これはインタプリタで1つ1つ解釈されて実行される処理と対極にある、言語処理系内部の処理を意味しています。言語仕様に「プリミティブ型」があるかどうかは、あまり関係ないので気をつけましょう。

ちなみに、型としてのプリミティブ型が必要なのは、本質的に静的型付けされていて、かつ多態性のある言語だけではないでしょうか。プリミティブ型はそれ自体をObject型に変換できません。Object型にすると、実行時まで処理ルーチンが特定できないことが多々あります。それに対して「型」が特定されていればコンパイル時に処理内容が特定できるので最適化ができます。上の(b)の処理が不要になります。逆に処理が特定できれば速いわけで、C++でvirtual関数のない「Integerクラス」を自作したら相当速くなるんじゃないかと思います。

結局Goslingさん曰く

で、これを踏まえて、元記事の主張をCRubyの処理系の言葉で書くと

「処理系の一番時間がかかるクラスはC言語のモジュールで書きましょう」

ということなので、これはRubyの組み込みクラスではされていることです。
JavaScriptは組み込みクラスのことを「プリミティブ型」と呼んでいるから混乱するんですよね。うーん。

本当に残った問題点

言語仕様と処理速度の問題は、背後の設計思想と実装の本質を知らなければ話すことができない部分です。
Rubyは「プリミティブ処理があるけど(現状では)遅い」というのが事実なわけで、問題の本質が語られないまま「プリミティブ型が速い」という言葉が一人歩きする状態は非常に危険で心配です。