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

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

新規登録して質問してみよう
ただいま回答率
85.50%
コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

Q&A

解決済

4回答

2542閲覧

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

otaks

総合スコア223

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

0グッド

0クリップ

投稿2016/10/01 21:21

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

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

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MIURA_Yasuyuki

2016/10/02 00:18

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

2016/10/02 02:15

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

回答4

0

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

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

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

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

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

facebook社での実例

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

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

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

投稿2016/10/03 22:46

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otaks

2016/10/05 22:03

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

0

ベストアンサー

・文字列型が存在する
・メモリ確保・開放を考えなくてもよい
これなら、コンパイル言語である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 05:11

intelf___

総合スコア868

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otaks

2016/10/02 09:37

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

2016/10/06 07: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 ...省略 ここまでくると正直自分にはよくわかりません。
guest

0

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

  • RPython

Pythonにいくつかの制約を加えてコンパイル出来るようにした言語。PyPyをコンパイルするのにも使われ、PyPyのソースに含まれるらしい。
※ PyPyはJITコンパイラを使用して高速化したPythonの実装。

Rubyを静的型(型推論あり)にし、コンパイル出来るようにした言語(ただし、Rubyのいくつかの機能は実装されていない)。型推論がうまく働けば、Rubyのスクリプトがそのまま通る場合も多い。

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

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

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

投稿2016/10/02 00:51

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otaks

2016/10/02 02:21

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

0

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

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

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

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

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

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

投稿2016/10/02 12:51

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otaks

2016/10/02 21:57

JITは当然知っています。 >一歩譲って、機械語のほうが早いとしてもせいぜい差がついて2倍程度です。 ソースを出してください。この質問を投稿する前に言語の実行速度を比較したサイトを いくつか参照しましたが、とても2倍程度ではありませんでした。(JITを使用した後でも) >知識のないプログラマがコーディングするとあっという間に10倍、100倍の差がつきます。 例を出してもらえますか?そんな状況が想像できません。 >3年経てばCPUの性能が倍以上あがる21世紀においては、 常に最新のハードを使えるわけではありません。 古いハードウェアで高速に動作することを求められる環境があります。
mit0223

2016/10/03 00:39

>一歩譲って、機械語のほうが早いとしてもせいぜい差がついて2倍程度です。 > ソースを出してください。この質問を投稿する前に言語の実行速度を比較したサイトを いくつか参照しましたが、とても2倍程度ではありませんでした。 https://www.techempower.com/benchmarks/ >>知識のないプログラマがコーディングするとあっという間に10倍、100倍の差がつきます。 > 例を出してもらえますか?そんな状況が想像できません。 以下は両方とも標準入力から1Gbytes を読み込むプログラムですが、約10倍の性能差があります。 改善前 $ cat a.c #include <stdio.h> #define SIZE 1000 #define COUNT 1000000 int main() { int i = 0; int buf[SIZE]; for (i = 0; i < COUNT; i++) { read(0, buf, SIZE); } } $ cc a.c $ time ./a.out < /dev/zero real 0m0.598s user 0m0.122s sys 0m0.467s 改善後 $ cat a.c #include <stdio.h> #define SIZE 1000000 #define COUNT 1000 int main() { int i = 0; int buf[SIZE]; for (i = 0; i < COUNT; i++) { read(0, buf, SIZE); } } $ cc a.c $ time ./a.out < /dev/zero real 0m0.065s user 0m0.001s sys 0m0.060s
mit0223

2016/10/03 01:54

> JITは当然知っています。 質問の内容から、JITコンパイラのことをご存じないものだと思い込んでしまいました。失礼しました。
otaks

2016/10/03 22:12

>一歩譲って、機械語のほうが早いとしてもせいぜい差がついて2倍程度です。 >> ソースを出してください。この質問を投稿する前に言語の実行速度を比較したサイト>を >いくつか参照しましたが、とても2倍程度ではありませんでした。 >https://www.techempower.com/benchmarks/ 上記のサイトはwebフレームワークの実行速度を一覧化したもので、 言語間の純粋な実行速度比較を見るものではないと思いますが、 このサイトの提示理由を教えていただけますか? 自分が参照したサイトは以下のサイトです。 (いずれも「言語 実行速度 比較」でググると出てくるサイトです) http://maplesystems.co.jp/blog/programming/2015.html http://hamukazu.com/2016/02/09/c-python-ruby-benchmark/ http://h-miyako.hatenablog.com/entry/2015/01/23/060000 >>>知識のないプログラマがコーディングするとあっという間に10倍、100倍の差>がつきます。 >> 例を出してもらえますか?そんな状況が想像できません。 >以下は両方とも標準入力から1Gbytes を読み込むプログラムですが、約10倍の性能差>があります。 少しだけ納得する部分もありますが、1Gbytesを読み込むことはそうそうないと思いますので、より汎用的な例を見てみたいです。
mit0223

2016/10/04 03:03

> 言語間の純粋な実行速度比較を見るものではないと思いますが、 > このサイトの提示理由を教えていただけますか? もともと、私の主張は「スクリプト言語は遅くない。どうしてコンパイラにこだわるの?」ってことでしたので、 otaks さんが「言語間の純粋な実行速度比較」のみに興味がおありでしたら、私の主張はまと外れですので、無視してください。 アプリケーションを開発する場合の言語処理系を選択する際に、コンパイラ言語にこだわる必要があるかどうかについて、議論しようとしただけです。興味がなければ、捨て置いてください。 > より汎用的な例を見てみたいです。 ちょっと素人すぎるかもしれませんが実際にあった例です。 ・DBに接続するのにコネクションプーリングを使わない ・Java の正規表現コンパイラをマッチングのたびに呼び出す ・DOM の appendChild で大量の子要素を追加する ・大量のテキストから文字列を検索するのに1文字ずつずらして比較している(KMP法やBM法を知らない) 逆に性能を上げるためにゴチャゴチャやっているのに効果をあげてないのもたまにあります。性能問題の基本は、「推測するな、計測せよ」です。
otaks

2016/10/05 22:03

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

2016/10/06 08:14

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問