Julia : スクリプト言語最速? 手軽さと速さを求めた科学技術計算向け言語

一般的に Ruby, Python といったスクリプト言語は手軽に書けるけど、遅いという特徴があります。
今回はスクリプト言語でありながら、速度も求めた Julia という言語を紹介します。 Julia は科学技術計算向けですが、汎用的な用途にも使えると思います。

ちなみに計算時間は速いみたいですが、立ち上がりがすごく遅いので、 タイトルにはちょっと偽りがあります。

科学技術計算向け言語

先に科学技術計算の分野と、よく使われている言語について簡単に説明します。

科学技術計算というのは線形代数、数値解析、統計解析など専門的な数値計算をする分野です。 大抵のアプリではディスクアクセスやネットワーク通信が先にスピードネックになることが多いので、 純粋に言語としての速度が求められる分野でもあります。

数値計算に関しては Fortran という言語が大昔からあります。 これは簡単なものに限定すれば、いまでも最速の部類です。
ただし、総合的に見た場合は C, C++ 言語の方が速いことが多いです。 また、実用性も高いので、速いプログラムを作りたい場合には C, C++ 言語が使われるのが普通です。

しかし、 C, C++ 言語は実装が大変です。 手軽に作りたいといえば、スクリプト言語です。
スクリプト言語の中では比較的 Python が科学技術計算に強いと言われています。


ただ Python はもともといろんな用途に使える汎用のプログラミング言語です。 専門的な計算用のライブラリーなどをたくさん用意し、計算の処理をより書きやすいように特化したものが 科学技術計算向け言語です。
このジャンルでは R 言語MATLAB が有名どころだと思います。
MATLAB は正確には数値解析ソフトウェアであり、その中で使われているプログラミング言語です。 これは商用なので、互換性のある GNU OCtave といった言語もあります。

Julia とは

Julia も R 言語や MATLAB のような科学技術計算向けの言語です。 すでに大御所的な言語がある中、なぜ Julia が作られたかというと書きやすさ、速さなどのためです。
Julia は書きやすいスクリプト言語でありながら、速さも売りにしています。

速度

Julia のサイトにでているベンチマークによればですが、 Fortran や C 言語の 2 倍弱ぐらいの遅さで収まっています。
Native 言語と比べるともちろん遅いのですが、 スクリプト言語との比較では、 R 言語や MATLAB とは数百倍、 Python では数十倍の速さです。 速いと言われている JavaScript の V8 エンジンと比べても倍ぐらいは速いです。
ただし、これらはだいたいの値です。実際は演算によって結構ばらつきがあるので、 詳しく知りたい方はサイトのベンチマーク結果を確認して下さい。

この速さの秘密は LLVM実行時(JIT)コンパイルにあります。
以前の記事で LLVM の JIT コンパイルはオマケみたいなものと書いていましたが、 こんなに速い言語ができるとは思っていませんでした。 ただし、使ってみた感覚では立ち上がりがかなり遅く、 むしろ他のスクリプト言語よりも遅いです。 ベンチマークは計算時間だけを測ったものではないかと思います。

また、言語のサイトではスクリプトとしても動作するし、 コンパイルもできるといったことも書いてあったのですが、 やり方がよくわかりませんでした。

型システム、構文

型システムはオブジェクト自体が型情報を持つ動的型付けです。 しかもちゃんと関数の引数での型チェック機能も持っています。
ただ、自動ジェネリックもやっているみたいなことも書いてあったので、 内部的には静的型付けみたいなこともやっているのかもしれません。 どちらにしろ、型を指定する手間はいらないけど、 必要なところだけちゃんと指定できるようになっています。 構文は MATLAB をベースとして Perl, Python, Ruby といったメジャーなスクリプト言語の要素を取り入れて改良しています。
個人的には主に Ruby の要素が取り入れられているように感じました。そのため、結構書きやすい構文になっていると思います。 また、 Lisp 的な考え方も入っているようです。

パラダイム

言語のパラダイムとしては オブジェクト指向関数型プログラミングのマルチパラダイムになっています。
関数型は最近 はやり のパラダイムで並列処理に強いという特徴があります。

さらに Julia では、より簡単に並列処理や分散(クラウド)コンピューティングできるようにもされています。 マルチコアや複数台での計算などによっても計算時間を短縮することを狙っているようです。

C, Fortran との親和性

新しい言語はシャアの低さやライブラリーの少なさが気になるところです。
しかし、 Julia ではラッパーなどなしで C や Fortran のライブラリーを直接呼び出せるようになっています。 C++ ではないところが残念ですが、 2 つの言語の大量のライブラリーを使えるようになりますし、 速度を上げることもできます。

汎用性

Julia を科学技術計算向け言語として説明してきましたが、 Julia は汎用性も考えられています。 正規表現による文字列処理などもできますし、十分に汎用プログラミング言語の機能もある と思います。

インストール

Windows 環境でのインストール方法について説明します。
といっても、圧縮ファイルをダウンロードして展開するだけです。


まず、ダウンロードページから圧縮ファイル(juliaX.X.X-....zip)をダウンロードし、 適当なファルダーに展開します。 展開したフォルダーにある julia.bat が実行ファイルです。
よく使う場合は、このフォルダーを環境変数 PATH に追加して下さい。

使い方

Julia を使う場合は以下の 2 つの使い方ができます。
  1. 対話モード(repl)
  2. スクリプト
2 つの使い方について簡単に説明します。 詳しくは -h でヘルプが表示されるのでそちらをご覧下さい。

対話モード(repl)

引数を指定せずに実行すると対話モードになります。

lang_julia_interactive.png

終了する場合は quit()を入力します。
ans は直前に評価した式の値を見る場合に使用します。

因みに対話モードは eshell 上でも動作します。

スクリプト

スクリプトとして実行する場合には、引数にソースファイルを指定します。
ソースファイルの拡張子としては "jl" が使われるようです。
~/lang/jl $ julia.bat hello.jl 
Hello, Julia!
また、Perl や Ruby のように -e によるワンライナーもできます。
~/lang/jl $ julia.bat -e "println(\"Hello, Julia!\")"
Hello, Julia!

Emacs モードの設定

Julia 用の Emacs モードのインストールと設定について説明します。
julia-mode はまだパッケージになっていないようなので、手動でインストールする必要があります。


まず、以下のページから julia-mode.el をダウンロードします。 ファイル 1 つだけでなので、 [Raw] を右クリックして [名前を付けてリンク先の保存] で保存します。 詳しいダウンロード方法は以前の記事を見て下さい。 ダウンロードしたファイルを load-path の通ったフォルダーに置きます。

以下の記述を ~/.emacs.d/init.el (~/.emscs.el) に追加すると *.jl のファイルで julia-mode となります。
(autoload 'julia-mode "julia-mode" "Emacs mode for Julia" t)
(add-to-list 'auto-mode-alist '("\\.jl\\'" . julia-mode))
細かいことをいうとちょっと修正するところがあります。 よくわからないという場合はそのままでも問題有りません。
元のインストールの説明では "julia-mode.el" を起動時にロードするようになっていました。 そこを autoload にしたため、 auto-mode-alist への追加が 2 重になっています。
julia-mode.el の方の行は削除しておいて下さい。

サンプルコード

Julia について私が興味を持ったところをサンプルを挙げて説明します。


関数定義でオプショナルな型指定が可能です。
日本語を使用する場合はシグネチャーなしの UTF-8 でファイルを保存しておきます。
# 関数定義, オプショナルな型指定
function multi(x::Int, y)
    x * y
end


str = ""
# 1 - 5 の範囲指定
for n in 1:5
    # 文字列の結合は + ではなく、 string
    # $ 表記による文字列内の評価
    str = string(str, "$(multi(n, 2)) ")
end
println(str)
~/lang/jl $ julia.bat func.jl 
2 4 6 8 10 

掛け算は * ですが、数式的な表現もできます。
function f(x)
    x^2 + 2x - 1
end

println("f(5) = $(f(5))")
~/lang/jl $ julia.bat math.jl 
f(5) = 34

Julia では関数がファーストクラスですので、変数や関数の引数(高階関数)に入れることができます。 無名関数も使えます。
ちなみに map(func, ary) は配列 ary に関数 func を適用して新しい配列を返す関数です。
src = [3, 0, -5, -8]
println("src  = $src")

# 無名関数を引数に渡す
ary = map(x-> (x < 0) ? -x : x,
          src)
println("ary  = $ary")

# ブロックで指定した無名関数
ary2 = map(x->begin
               if x < 0 && iseven(x)
                   return 0
               elseif x == 0
                   return 1
               else
                   return x
               end
           end,
           src)
println("ary2 = $ary2")
~/lang/jl $ julia.bat lambda.jl 
src  = [3, 0, -5, -8]
ary  = [3, 0, 5, 8]
ary2 = [3, 1, -5, 0]

Ruby の長所の 1 つとしてエレガントなコードブロックがあります。
Julia でもブレース {} ではありませんが、 Ruby 風のコードブロックが使えます。
# Ruby 風のコードブロック
ary = map([3, 0, -5, -8]) do x
    if x < 0 && iseven(x)
        return 0
    elseif x == 0
        return 1
    else
        return x
    end
end
println(ary)

# data フォルダーに移動して、ファイルに書き込み
cd("data") do
    open("outfile.txt", "w") do f
        write(f, "foo\n")
    end
end
~/lang/jl $ julia.bat block.jl 
[3, 1, -5, 0]
~/lang/jl $ cat data/outfile.txt 
foo

Julia では演算子も式 です。この辺は Lisp 的な考え方が入っています。
a = 1 + 2 + 3
b = +(1, 2, 3)
f = +;
c = f(1, 2, 3)

println("$a $b $c")
~/lang/jl $ julia.bat op.jl
6 6 6

Eval や Lisp 的なマクロも使えます。
# Eval
exp = :(a + b)  # : をつけるとシンボルになる
a = 1
b = 2
println("$(eval(exp))")
~/lang/jl $ julia.bat meta.jl 
3
# Macro
macro assert(ex)
    :($ex ? nothing : error("Assertion failed: ", $(string(ex))))
end
@assert 1==0
@assert 1==0 は次のように展開されます。
1==0 ? nothing : error("Assertion failed: ", $(string("1==0")))

感想

私の場合は、科学技術計算と呼ばれる分野はごくたまにやる程度ですが、 基本的に C++ を使います。これは次のような理由で選んでいます。
  • 速度を要求される
  • アプリのコアな部分なので、リバースエンジニアリング対策で Native
  • 使いたいライブラリーがある
Julia でもコンパイルができるようになれば、 Julia に変えることもできるのですが、 今のところ できないみたいなので残念です。
ただ、今でも検算用のプログラムを作るのには使える気はします。


汎用プログラミング言語として見た場合は、かなりいい言語だと思いました。 特に気に入ったのは次の部分です。
  1. C, Fortran のライブラリーが直接呼び出せる
  2. Ruby 風のエレガントなコードブロック
  3. オプショナルな型チェック
  4. オブジェクト指向と関数型のマルチパラダイム
しかし、いかんせん遅すぎます。 速さを売りにしているはずなのですが、立ち上がりの遅さは結構気になる程です。
ただ、 JVM で動作するアプリと違い、コンパイルできるようになれば、 速度の問題は解決するのではないかと思います。


コンパイルや速度に問題はありますが、 Julia 自体と Windows 環境の LLVM がまだ開発段階なので、 今後に期待したい言語です。


関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

No title

>Julia のサイトにでているベンチマークによればですが、 C 言語の 2 倍弱ぐらいの遅さで収まっており、 Fortran とは同程度です。

Juliaのサイトに出ているベンチマークの意味ですが、「JuliaはCと同程度で(比率がほぼ1)、
一方Fortranはその2つに比べて数十%以上高速(fibは約4倍高速、ただしparse_intは
異様に遅い)」という風に見えるのですが・・

No title

ああ、すいません。「数十%高速」なのはpi_sum、rand_mat_stat, fibで他のテストは
Fortran ~ Cという感じのようです。

それはさておき、C++もFortran>=2003もPythonなどのスクリプト言語に比べるとコーディングが
面倒なことは変わらないので、Juliaのように「書くのが楽で、かつそこそこ速度が出る
言語」というのがもっと出てきて欲しいなー、と思ったりです。

Re: No title

Fortrun は速いものは C よりも速いのですが、結構ばらつきが大きく、Julia と同程度と書いていました。
ただ、記事を書いていた時と表の値が少し変わっていて、今の表は確かに C と同程度のものが多くなっているみたいです。記事の方を修正しておきます。

書きやすくかつ速い言語は私もすごく欲しいです。
ただ、書きやすさと速さはトレードオフの面があるので、なかなかありませんが、今後は LLVM が成熟していけば、Julia のような言語は増えてくるのではないかと思います。

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
44位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
6位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

05月 | 2017年06月 | 07月
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。