質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.61%

スクリプト言語をコンパイル?

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 1,496

otaks

score 218

スクリプト言語で、機械語を出力することはできないのでしょうか?

スクリプト言語は使いやすいです。例えばCに比べて、
・文字列型が存在する
・メモリ確保・開放を考えなくてもよい
等、作りたい処理に直接的に関係しない処理の作成に手間をかけずに
済むからです。

各スクリプト言語には、それぞれ各言語の仕様が存在していると思います。
それらの仕様に従って機械語を出力することができれば、簡単な構文で
余計なところに頭を使わずにプログラミングできると思います。

実装の難易度もHaskell等の関数型言語を使うと、ルールを羅列するような
プログラムは書きやすいと聞いたことがあるので、それほど難なく実装可能かと
推測します。(自分にはそんなものを作れる能力ありませんが...)

何か、スクリプト言語はインタプリタ実行しなくてはならない理由があるのでしょうか?
例えば、型は実行時に動的に決まるから、コンパイル時に確定できないのだとか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • MIURA_Yasuyuki

    2016/10/02 09:18

    GHC(Haskell)はコンパイルする機能があります。
    そもそも、機械語を出力したい目的はなんでしょう?目的によってはコンパイル以外の手段が適切かもしれませんよ。

    キャンセル

  • otaks

    2016/10/02 11:15

    機械語を出力したい目的は実行速度が速いことです

    キャンセル

回答 4

checkベストアンサー

+3

・文字列型が存在する 
・メモリ確保・開放を考えなくてもよい
これなら、コンパイル言語であるgolang(go言語)でもできます。

性能

  • 実行速度
    cとあまり変わらない速度
    cの有名なint型ヒープソート→20万件 22ms
    golangの自作int型クイックソート→20万件 25ms

  • メモリ
    ヒープ領域を自動で確保、解放してくれる
    c→30万件でスタックオーバーフロー
    golang→1億件で正常に動作

言語としての特徴

  • 文字列型
    string, []byte, []runeの三つが主体です。
    byteはバイト単位で分割したもの(マルチバイト文字はばらける)
    runeは文字単位で分割したもの

  • 強み
    並列処理、ネットワーク通信、学習コストの低さ

  • クロスコンパイル
    windowsのexeファイルからLinuxの実行ファイルはもちろん、名前の知らないようなOSやその32/64bitまで対応しています。
    対応OSやCPUアーキテクチャ詳細
    https://golang.org/doc/install/source#environment

  • 他言語との連携
    cgoという仕組みでC言語の関数を呼び出したり、モバイルアプリ開発ではgomobileのbindという仕組みでJavaやObjective-Cから呼び出されるライブラリを生成することができます。
    dllという形式のライブラリファイルの関数を簡単に呼び出すことができます。

おすすめ参考サイト

  • 英語
    ダウンロード https://golang.org/dl/
    ドキュメント https://godoc.org/
    ドキュメント他 https://golang.org/doc/

  • 日本語
    学習サイト https://go-tour-jp.appspot.com/
    逆引き http://ashitani.jp/golangtips/


何か、スクリプト言語はインタプリタ実行しなくてはならない理由があるのでしょうか? 

インタプリタの方が実装が簡単です。なので比較的コストを掛けずに作るならインタプリタがいいんでしょう。
golangはスクリプト(動的型付けもする)言語ながらコンパイルが主体なので、インタプリタ実行しなくてはならないというわけではないです。

機械語を出力したい目的は実行速度が速いことです

それほど実行速度を求められるプログラムを作ろうとしてるのですか?
差し支えなければ教えていただきたいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/02 18:37

    golang、良さそうですね。最近golangに関する書籍、webサイトも少しづつ充実してきているように感じます。

    キャンセル

  • 2016/10/06 16:59

    ありがとうございます。蛇足ですが、ベストアンサー記念に
    ---
    ほとんどの場合メモリ確保・解放の意識をするだけでかなり(cに近いくらい)高速なはずです。
    append(配列の結合)、string型の足し算(つまりappend)、string⇔[]byteのキャストなどはループ内で頻繁に行わない方がいいですね。
    例えば、appendを使ったクイックソートは使わないクイックソートよりも10倍以上遅かったです。
    Cと違ってメモリの確保を自動でやってくれますが、それが速度の低下につながるのでよっぽど高速にしたいときはメモリをどういう条件で確保・解放するかを把握しましょう。

    さらに高速にしたいときはgo標準のベンチマークで実装した関数を比較できます。
    ・コマンド
    go test -bench
    ・パッケージ
    testing
    比較対象のソースを書き換える必要があるのでちょっと面倒です。

    さらに高速にしたいときはアセンブリを見てみるといいかもしれません。
    (大変なので、命令数の比較やメモリ確保のチェックだけでも)
    ・x86_64でアセンブリを表示するコマンド(多分Linux系のみ)
    go tool 6g -S server.go
    ・結果の例
    0000 (server.go:12) TEXT handler.ServeHTTP+0(SB),$272-24
    0001 (server.go:12) FUNCDATA $0,gcargs·0+0(SB)
    0002 (server.go:12) FUNCDATA $1,gclocals·0+0(SB)
    0003 (server.go:12) TYPE h+0(FP){"".handler},$0
    ...省略
    ここまでくると正直自分にはよくわかりません。

    キャンセル

+3

制限付き、または、一部仕様が異なる、という点がありますが、スクリプト言語を、そのまま、または、一部変更することで、コンパイルして機械語(ネイティブ)できる言語があります。

  • RPython
    Pythonにいくつかの制約を加えてコンパイル出来るようにした言語。PyPyをコンパイルするのにも使われ、PyPyのソースに含まれるらしい。
    ※ PyPyはJITコンパイラを使用して高速化したPythonの実装。
  • Crystal
    Rubyを静的型(型推論あり)にし、コンパイル出来るようにした言語(ただし、Rubyのいくつかの機能は実装されていない)。型推論がうまく働けば、Rubyのスクリプトがそのまま通る場合も多い。

また、逆の発想で、HaskellやScala等の一部の言語ではインタプリタも一緒に用意されて、スクリプト言語のように扱えるようになっている場合もあります。

制限や一部の変更が無い、スクリプト言語そのもののコンパイラが作れないのかというと、かなり難しいらしいです。Rubyについてですが、Rubyだとあまりに動的で柔軟な言語仕様のせいで、Cのようなコンパイラを作りたくても作れないととある記事に書いてありました。Crystalのように静的型の導入し、一部機能を削らないと無理なのではないかと思います。

【補足】
事前に機械語までコンパイルしているAOTコンパイラはありますが、言語処理系が完全に省けるわけではありません。また、研究段階のようであり、実用的な物はまだないようです。生成したバイナリの移植性の問題もあるため、目に見える速度向上が無ければ、JITコンパイラや中間コード生成がしばらくは主流になると思われます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/02 11:21

    RPython、Crystal の存在は知りませんでした。とても参考になります

    キャンセル

+3

 まず、前提条件をおうかがいします

  • どんなプログラムを高速化したいのか
  • どれだけ高速化したいのか
  • 高速化することにどれだけの価値があるのか(≒高速化のためにどれだけの工数を割けるのか)

趣味や競技などで、「特定の演算を、1マイクロ秒でも速くしないといけない」という場面であれば、最初からC/C++で書く、というのがいちばん妥当な選択肢となります(これらは見えないオーバーヘッドのたぐいがほとんど発生しない言語です)。

一方で、Webアプリの場合、どうせ通信時間やDBへのアクセス時間はミリ秒単位で発生してしまうので、プログラム自体を速くすることでの利点というのも、一定限度を超えればあまりユーザー側での価値がなくなってしまいます(少し前にそういう質問がありました)。

あと、機械学習系のライブラリなども、速度を要求されるコア部分は機械語で進むようになっていて、データの入出力はスクリプト言語で便利にできる、というような構造になっていることもあり、こういう場合も入出力部分を改善したところでほとんど高速化しない割に、データのハンドリングがめんどくさくなります。

 facebook社での実例

facebookはPHPでシステムを組んでいたのですが、PHPの遅さがネックになってきたので、「HipHop for PHP」として、PHPをC++に変換してコンパイルできるような仕組みを作りました。ところが、

  • コンパイルに時間がかかることので本番反映のコストになる
  • 開発時にコンパイルを待てないので、同じ動作をするインタプリタが別途で必要になって二重投資になる
  • ある程度のところで性能が頭打ちになった

というような事情があったところで、JIT型のHHVMを作って改良していくとそちらのほうが高性能となったこともあって、コンパイル型の開発は打ち切られています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/06 07:03

    残念ですが守秘義務のため回答できません。

    キャンセル

+1

スクリプト言語は遅くない!

JIT(Just In Time)コンパイラという言葉をご存知でしょうか。 実行時に機械語にコンパイルする方式で、Javaなど多くの言語処理系で実装されており、単なる繰り返し処理などにおいては、実行速度においてネイティブのコンパイラとほぼ遜色ないと言われています。スクリプト言語の例でいいますと、Javascript の言語処理系である node.js はJITを実装しています。

また、機械語を出力するかどうかで性能が決まると考えておられるようですが、同じ機械語でも、コンパイラの得意、不得意やキャッシュ管理との相性ですぐに性能が2,3倍の性能差がでたりして、スクリプト言語より遅かったりします。

性能問題については、実際にその問題がでてから対応策を検討すべきです。長いことこの仕事をしており、何度も性能問題に対応したことがありますが、言語処理系の選択が間違っていたという結論になったことは一度もありません。

一歩譲って、機械語のほうが早いとしてもせいぜい差がついて2倍程度です。これに対して、知識のないプログラマがコーディングするとあっという間に10倍、100倍の差がつきます。

20世紀は言語を選ぶ際にその性能が注目されましたが、3年経てばCPUの性能が倍以上あがる21世紀においては、言語処理系の性能で何かを議論するのはナンセンスです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/04 12:03

    > 言語間の純粋な実行速度比較を見るものではないと思いますが、
    > このサイトの提示理由を教えていただけますか?

    もともと、私の主張は「スクリプト言語は遅くない。どうしてコンパイラにこだわるの?」ってことでしたので、 otaks さんが「言語間の純粋な実行速度比較」のみに興味がおありでしたら、私の主張はまと外れですので、無視してください。
    アプリケーションを開発する場合の言語処理系を選択する際に、コンパイラ言語にこだわる必要があるかどうかについて、議論しようとしただけです。興味がなければ、捨て置いてください。

    > より汎用的な例を見てみたいです。
    ちょっと素人すぎるかもしれませんが実際にあった例です。

    ・DBに接続するのにコネクションプーリングを使わない
    ・Java の正規表現コンパイラをマッチングのたびに呼び出す
    ・DOM の appendChild で大量の子要素を追加する
    ・大量のテキストから文字列を検索するのに1文字ずつずらして比較している(KMP法やBM法を知らない)

    逆に性能を上げるためにゴチャゴチャやっているのに効果をあげてないのもたまにあります。性能問題の基本は、「推測するな、計測せよ」です。

    キャンセル

  • 2016/10/06 07:03

    議論がかみ合っていない気がしますが、根拠もなく
    >一歩譲って、機械語のほうが早いとしてもせいぜい差がついて2倍程度です。
    と言い切ってるということですか。







    キャンセル

  • 2016/10/06 17:14

    > 根拠もなく
    >>一歩譲って、機械語のほうが早いとしてもせいぜい差がついて2倍程度です。
    >と言い切ってるということですか。
    はい、そうです。たいした根拠はございません。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る