WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

Dart VM上のPython実装 Medusaを試す

サーバーエンジニアの原です。

2011年にDartというプログラミング言語がGoogleから発表されましたが、 そのランタイムであるDart VMは、以下のような特徴を持っています。

  • JITコンパイラ
  • スループット重視
  • Threadの代わりにIsolateを採用
  • Isolate単位でヒープ・GC・コンパイラを持つ
  • Snapshotによる高速起動

このDart VMの特徴を活かした・・・かどうかは正直まだわかっていませんが、 Dart VM上で動作するPython実装の Medusa というプロジェクトを見つけたので、 試してみました。

Medusaは、「がっつりPython書くと重くなる。なんかDart VMってのが出てきて速そうだからPython乗っけてみた」的なノリ(失礼)で実装されているようです。

おそらく日本で初めて言及する = 誰得だと思いますが、 一応ベンチマーク取ってみたいと思います。

インストール手順

OS X 10.10.2 でのインストールを想定しています。

前提

あらかじめXcodeをインストールしておいてください。 Python2.7がパスを通ってない場合は、必要である場合はインストール後にパスを通してください。

Qt5のインストール

現在のMedusaのビルドには、Qt 5という開発環境に含まれるqmakeというコマンドが必要であるため、 Qt5をインストールする必要があります。

QtプロジェクトサイトからCommunity Editionのインストーラをダウンロードしてください。

ダウンロード後に実行すると、インストーラが起動します。

任意の場所にインストール後、以下のようなコマンドを実行し、qmakeをPATHに追加してください。

(ホームディレクトリ上にインストールしたことを前提としています。)

$ echo 'export PATH="$HOME/Qt/5.4/clang_64/bin:$PATH"' >> ~/.bash_profile

Dartのインストール

Dartの実行環境であるDart VMも同様に別途インストールする必要があります。

Homebrewでは、以下のコマンドでインストールできます。

$ brew tap dart-lang/dart  
$ brew install dart  

Dart公式サイトからダウンロードすることでもインストール可能です。

Medusaのビルド

以下のように、Githubからソースを取得し、ビルドします。

$ git clone git@github.com:rahul080327/medusa.git  
$ cd medusa  
$ ./INSTALL.mac  

Medusa 2.7.3 Successfully installed Yo! Runnable directly as 'medusavm' from the terminal. Happy Pythoning! のようなものが出たらインストール成功です。

medusavmコマンドで、PythonコードからDartコードへの変換やプログラムの実行を行うことができます。
残念ながら、Dart VMがインタプリタをサポートしていないのでREPLはありません。

ベンチマークの実行

以下の3つのプログラムを簡単にベンチマーク取ってみます。

fib.py - みんな大好きフィボナッチ

def fib(n):  
    if n < 2:  
        return n  
    return fib(n - 1) + fib(n - 2)  
  
fib(32)  

string.py - とりあえず文字列操作を大量に

loop = 1000 * 1000  
  
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]  
for i in xrange(loop):  
    s = "".join([s + str(i) for s in days])  
    print s  

takeuchi.py - 再帰ベンチマークの雄

def t(x, y, z):  
    if x <= y:  
        return y  
    else:  
        return t(t(x - 1, y, z), t(y - 1, z, x), t(z - 1, x, y))  
  
t(13, 8, 0)  

これらのプログラムを、以下の4つの方法で実行し、timeコマンドで実行時間を計測します。

  • CPython 2.7.9
  • PyPy 2.5.0
  • medusavmコマンドから直接実行(Medusa 2.7.3 beta + Dart 1.8.5)
  • medusavm -cで生成したDartコードを実行(Medusa 2.7.3 beta + Dart 1.8.5)

Pythonの各ランタイムはpyenvでインストールしました。

$ pyenv install 2.7.9  
$ pyenv install pypy-2.5.0  

実際のベンチマークには、以下のシェルスクリプト(zsh)を実行しました。

#!/bin/zsh  
  
# CPython 2.7.9  
pyenv local 2.7.9  
time python fib.py > /dev/null  
time python string.py > /dev/null  
time python takeuchi.py > /dev/null  
  
# PyPy 2.5.0  
pyenv local pypy-2.5.0  
time python fib.py > /dev/null  
time python string.py > /dev/null  
time python takeuchi.py > /dev/null  
  
# medusavm直接実行  
time medusavm fib.py > /dev/null  
time medusavm string.py > /dev/null  
time medusavm takeuchi.py > /dev/null  
  
# Medusaで生成したDartコードを実行  
rm -f ./fib.dart ./string.dart takeuchi.dart  
medusavm -c fib.py  
medusavm -c string.py  
medusavm -c takeuchi.py  
time dart fib.dart > /dev/null  
time dart string.dart > /dev/null  
time dart takeuchi.dart > /dev/null  

ベンチマーク環境

  • MacBook Air (13-inch, Mid 2013)
  • OS X 10.10.2
  • 1.3 GHz Intel Core i5
  • 4 GB 1600 MHz DDR3

ベンチマーク結果

Python 2.7.9 PyPy 2.5.0 medusa dart only
fib.py u=1.30s
s=0.05s
c=95%
t=1.413
u=1.33s
s=0.03s
c=94%
t=1.446
u=0.39s
s=0.08s
c=59%
t=0.791
u=0.34s
s=0.03s
c=81%
t=0.456
string.py u=5.45s
s=0.06s
c=96%
t=5.703
u=5.12s
s=0.06s
c=95%
t=5.455
u=5.84s
s=2.34s
c=93%
t=8.710
u=5.94s
s=2.36s
c=93%
t=8.928
takeuchi.py u=20.94s
s=0.21s
c=95%
t=22.186
u=21.14s
s=0.22s
c=92%
t=22.988
u= 4.27s
s=0.14s
c=95%
t= 4.600
u= 4.36s
s=0.14s
c=94%
t= 4.765

  • u=ユーザーCPU時間, s=システムCPU時間, c=CPU使用率, t=処理合計時間
  • 数値後の英字はその数値の単位を表します。(sは秒、%はそのままの意味)

Dart VMのパフォーマンスが良好であることが非常に良く現れた結果となりました。

CPython, PyPyは文字列操作がDart VMと並ぶ結果となりましたが、文字列操作が最適化されているのでしょうか? また、Dart VMの結果ではシステムCPU時間が2s以上と悪い結果が出ています。 おそらく標準出力のシステムコールが行われていたためと推測できるのですが、CPython, PyPyでその結果が現れていないのは謎です・・・1

意外にも、Medusaから直接実行のケースと、MedusaでDartコードを生成してから実行で差がありませんでした。Pythonコードのパースのしやすさから得られた結果だと思います。

再帰はDart VMが圧倒的な結果となりましたが、Dart VMも末尾再帰の最適化をサポートしていないので、 これほど差が出るとは思っていませんでした。JITコンパイラによる最適化または計算結果のメモ化が行われた可能性が高いと思います。

まとめ

Medusaはまだ production ready とはとても言いがたいですが、パフォーマンスにこだわったDart VMで動作するPythonは非常に魅力的です。

多様性は善ですし、PythonもDartも割りと好きな言語(プラットフォーム)ですので、少なからずコントリビュートしていければと思っています。

Medusaを筆頭に、Dart VM上で動く他のプログラミング言語の実装が次々と出てくると、また面白いことになりそうです。 興味のある方は(大変でしょうが)実装してみてください。


  1. バッファがフラッシュされていないのでしょうか。詳細をお知りの方は是非教えて下さい・・・[]