初めまして、2023年2月にフォースタートアップス株式会社に入社したモジョモジョドレミことモジョリアンの江種(@hairinhi)と申します。現在、主にRuby on Railsで作られている社内向けプロダクト「タレントエージェンシー支援システム(SFA/CRM)」の開発、運用を担当しております。
はじめに
Mojoとは、Python構文の長所とシステムプログラミングおよびメタプログラミングを組み合わせることによって生み出された、研究と運用の間のギャップを埋める新しいプログラミング言語です。公式ドキュメントには、Mojoを使用すると、C言語よりも高速でPythonのエコシステムとシームレスに相互運用できる移植可能なコードを作成できると書かれています。
また、公式サイトではPythonよりも最大35000倍速く計算できると謳われています。Pythonのエコシステムを引き継ぎつつ高速に実行できるということで、AI分野での活躍が特に期待できますね。
今回はこのMojoをPythonと比較して、本当に35000倍速く計算できるのか確認してみたいと思います。
Mojoを試すには
現在(2023年7月時点)、Mojoは開発元のModular社が用意しているJupyterHub環境にあるMojo PlayGroundでしか試すことができません。ここでは、利用できるようになるための手順を簡単にご紹介します。
1. ユーザー登録
まず、こちらのサインアップページからユーザー登録を行なってください。
2. 招待メールを受け取る
ユーザー登録を行なって、数日待つと登録したメールアドレスに招待メールが届きます。早ければ、登録したその日に招待メールが来ることもあります。
3. Mojo Playgroundにアクセスする
招待メールにある「Access Mojo Playground」のリンクにアクセスすると、JupyterHub環境が起動して、Mojoを利用できるようになります。
性能比較をしてみました
このMojoがPythonよりもどのぐらい高速なのか気になったので、3つの簡単なアルゴリズムで性能比較をしてみました。
FizzBuzz問題
皆さんお馴染みのFizzBuzz問題で検証してみました。1 ~ 100までの数で試しています。
フィボナッチ数列
フィボナッチ数列もご存じの方が多いと思います。スクラム開発で各タスクにストーリーポイントを割り振る時にも使われますね。今回は30番目の値を求めてみます。
アッカーマン関数
アッカーマン関数とは計算可能であるが原始再帰的ではない、well-definedなTotal Functionの最も単純な関数であり、さらに1900年代初期に信じられていた「計算可能な関数はすべて原始再帰的でもある」という考えに対する反例でもあります。この関数は指数関数や多重指数関数よりも急速に増大していく関数であることが知られています。今回は第一引数を3、第二引数を12にして試してみました。
ご注意!
今回、MojoについてはMojo Playgroundで、Pythonについては私が普段業務で使用している以下のようなスペックのマシンで試しています。
MacBook Pro 2021 チップ: Apple M1 Max メモリ: 64GB macOS: Ventura 13.0 Pythonのバージョン: 3.11.1
よって、実行環境がMojoとPythonで違うので厳密な比較にはなっておりません。また、処理時間の計測にPythonではtimeitモジュールを使用し、Mojoでは処理開始時刻と終了時刻の差を計算しています。
あくまで参考程度にご覧ください。
Python
from timeit import timeit def fizz_buzz(n): if n % 15 == 0: print("FizzBuzz") elif n % 3 == 0: print("Fizz") elif n % 5 == 0: print("Buzz") else: print(n) def benchmark(): for i in range(1, 101): fizz_buzz(i) result = timeit(lambda: benchmark(), number = 1) print(result * 1000000000, "[ナノ秒]")
結果
1 2 Fizz 4 Buzz Fizz 〜〜途中省略〜〜 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz 136792.19409823418 [ナノ秒]
from timeit import timeit def fib(n): if n < 2: return n else: return fib(n-1) + fib(n-2) def benchmark(): print(fib(30)) result = timeit(lambda: benchmark(), number = 1) print(result * 1000000000, "[ナノ秒]")
結果
832040 98048625.04824996 [ナノ秒]
import sys from timeit import timeit # Pythonの場合再帰回数の上限を上げておく必要があります sys.setrecursionlimit(200000000) def ack(m, n): if m == 0: return n + 1 elif n == 0: return ack(m - 1, 1) else: return ack(m - 1, ack(m, n - 1)) def benchmark(): print(ack(3, 12)) result = timeit(lambda: benchmark(), number = 1) print(result * 1000000000, "[ナノ秒]")
結果
32765 45427333666.943016 [ナノ秒]
Mojo
from Time import now fn fizz_buzz(n: Int): if n % 15 == 0: print("FizzBuzz") elif n % 3 == 0: print("Fizz") elif n % 5 == 0: print("Buzz") else: print(n) start = now() for i in range(1,101): fizz_buzz(i) end = now() print(end - start, '[ナノ秒]')
結果
1 2 Fizz 4 Buzz Fizz 〜〜途中省略〜〜 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz 362569 [ナノ秒]
from Time import now fn fib(n: Int) -> Int: if n < 2: return n else: return fib(n-1) + fib(n-2) start = now() print(fib(30)) end = now() print(end - start, "[ナノ秒]")
結果
832040 2563558 [ナノ秒]
from Time import now def ack(m: Int, n: Int) -> Int: if m == 0: return n + 1 elif n == 0: return ack(m - 1, 1) else: return ack(m - 1, ack(m, n - 1)) start = now() print(ack(3, 12)) end = now() print(end - start, "[ナノ秒]")
結果
32765 4242469743 [ナノ秒]
比較
実行結果を表にまとめてみました。(単位はナノ秒)
アルゴリズム | Pythonの結果 | Mojoの結果 | 比較 |
---|---|---|---|
FizzBuzz問題 | 136792.19409823418 | 362569 | Pythonのほうが約2.6倍速い |
フィボナッチ数列 | 98048625.04824996 | 2563558 | Mojoのほうが約38倍速い |
アッカーマン関数 | 45427333666.943016 | 4242469743 | Mojoのほうが約10倍速い |
FizzBuzz問題については、意外にもPythonのほうが速かったです。これはMojoの標準出力がボトルネックになっていると思われます。それ以外については、期待通りMojoのほうが速い結果となりました。
考察
公式サイトにあるようにMojoのほうが 35000倍速い! という結果にはなりませんでした。そこで、もう一度公式サイトを見ると、比較表の下に注意書きでInstance AWS r7iz.metal-16xl Intel Xeon
と書かれていました。AWSのEC2インスタンスの中でR7izインスタンスというと、全コア最大ターボ周波数が3.9GHzの第4世代Intel Xeonスケーラブルプロセッサを搭載した初のEC2インスタンスとして知られています。またR7izインスタンスは、最大1,024GiBのメモリと最大128のvCPUを搭載しているので、金融・保険業界やデータ分析など高いパフォーマンスが求められる環境において最大限そのパフォーマンスを発揮することができます。
このことから言えるのは、Mojoは実行環境が良くなればなるほど、その真価を発揮できる可能性があるということです。今回の検証ではJupyterHub環境とMacBook Proを使用しました。「Pythonよりは速い」という程度の結果を得ることができましたが、一方で「まだまだ俺の力はこんなものじゃない」とMojoが語りかけているようにも思えました。
まとめ
FizzBuzz問題の結果は意外でしたが、概ねMojoのほうが速いということが分かりました。普段の業務では、AI関連の業務に関わることは少ないですが、個人的に非常に興味がある分野でもあります。これからもMojoについてはキャッチアップしていきたいと思います。
採用
最後に採用情報です。 当社では、まだまだ採用募集中です。ぜひ一緒にMojoについて語り合いましょう!ご興味ありましたらぜひ一度カジュアルにお話できたらと思います。 採用ページはこちら。
参考資料
https://zenn.dev/turing_motors/articles/e23973714c3ecf
https://www.kurims.kyoto-u.ac.jp/~cs/cs2011_terui.pdf