🚀

MojoがApple Silicon Macに対応したので早速試してみた

2023/10/20に公開

Pythonの高速なスーパーセットとされているMojoがApple Silicon Macについに対応したので、早速インストールしてMojo入門してみました。
https://www.modular.com/blog/mojo-is-now-available-on-mac
※ 記事作成日の前日(2023年10月19日)に公開されました。

インストール手順

0. ModularにSign up

https://developer.modular.com/signup?redirect=%2Fdownload

基本、上記から遷移した先の以下の場所に記載しているインストール方法に沿って入れていきます。(ちょっと詰まった部分あるので本記事ではそれも記載してます)

なお、curlコマンド部分に記載されているMODULAR_AUTHの値は本記事で {YOUR_TOKEN_HERE} となっている場所で使うため、メモっておきます。

1. (Homebrewインストールしてない方は入れておく)

2. Modular CLIをインストールする

$ curl https://get.modular.com | \
  MODULAR_AUTH={YOUR_TOKEN_HERE} \
  sh -
実行結果抜粋
Error: Your Xcode (14.1) is too outdated.
Please update to Xcode 15.0 (or delete it).
Xcode can be updated from the App Store.

Xcodeが古いと怒られたので、大人しくApp StoreからXcodeをアップデートする。
さらにライセンス同意のため sudo xcodebuild -license accept を実行したのち、再度curlコマンド実行したら成功しました。

3. Mojo SDKのインストール

$ modular install mojo
modular: error: please run `modular auth` before attempting to install a package

怒られたので、authコマンドを実行。

modular auth MODULAR_AUTH={YOUR_TOKEN_HERE}

改めて、installコマンド実行。

$ modular install mojo

以下が出たら成功。

実行結果抜粋
🔥 Mojo installed! 🔥

インストールされたMojoのバージョンを確認。

$ mojo --version
mojo 0.4.0 (9e33b013)

4. PATHを通しておく

$ echo 'export MODULAR_HOME="$HOME/.modular"' >> ~/.zshrc

$ echo 'export PATH="$MODULAR_HOME/pkg/packages.modular.com_mojo/bin:$PATH"' >> ~/.zshrc

$ source ~/.zshrc

5. VS Codeの拡張機能も入れておく

自分はVS Code愛用しているので拡張機能も入れました。
https://marketplace.visualstudio.com/items?itemName=modular-mojotools.vscode-mojo

Ackermann関数で速度比較してみる

計算量エグい(語彙力)でお馴染みのAckermann関数でPythonとMojoの速度比較をしてみます。

なお、今回のAckermann関数の実装については計算量を稼ぐため、メモ化など工夫せずに定義通りの単純な再帰で実装しています。

Python

ackermann.py
import sys
from time import time

# 再帰上限あげておかないと RecursionError で怒られるので注意
sys.setrecursionlimit(50000)


def ackermann(m: int, n: int) -> int:
    if m == 0:
        return n + 1
    elif n == 0:
        return ackermann(m - 1, 1)
    else:
        return ackermann(m - 1, ackermann(m, n - 1))


m, n = 3, 12
start = time()
result = ackermann(m, n)
exec_time = time() - start
print(f"result: {result}")
print(f"time: {exec_time} sec")
実行結果
$ python ackermann.py
result: 32765
time: 44.0684700012207 sec

Mojo

ackermann.mojo
from time import now


fn ackermann(m: Int, n: Int) -> Int:
    if m == 0:
        return n + 1
    elif n == 0:
        return ackermann(m - 1, 1)
    else:
        return ackermann(m - 1, ackermann(m, n - 1))


fn main() -> None:
    let m = 3
    let n = 12
    let start = now()
    let result = ackermann(m, n)
    let exec_time = (now() - start) / 1_000_000_000
    print("result:", result)
    print("time:", exec_time, "sec")
実行結果
$ mojo ackermann.mojo
result: 32765
time: 2.1486179999999999 sec

結果

  • 約20倍Mojoの方がはやかった。
  • (Pythonと違って再帰上限は特に設定しなくても問題なかった)

メモ

f-stringは未対応らしい

試しにf-stringで記述してみた際の結果
$ mojo ackermann.mojo
/Users/miotava/Documents/dev/mojo_test/ackermann.mojo:19:12: error: expected ')' in call argument list
    print(f"result: {result}")
           ^
mojo: error: failed to parse the provided Mojo

Issueも立ってるので近いうちに対応されるかも。
https://github.com/modularml/mojo/issues/398

拡張子が🔥でも実行できる

公式ドキュメントによれば拡張子を🔥としても実行できるそうなので試してみました。

$ mojo ackermann.🔥
result: 32765
time: 2.2284009999999999 sec

できた笑
遊び心がありますね。

スペースマーケット Engineer Blog

Discussion