ניסוי Mojo: פייתון רק על טורבו

13/07/2026

מוג'ו היא שפת התכנות החדשה של קריס לאטנר, היוצר של swift ושל LLVM. היא שפה מקומפלת עם טיפוסים חזקים ותחביר שמאוד מזכיר את פייתון. יש לה גם ממשק חיבור מובנה לפייתון. מטרתה המוצהרת היא להיות שפת התכנות לאפליקציות AI מאחר והיא גם מאפשרת חיבור מובנה לכל האקוסיסטם של פייתון אבל גם מספקת ביצועים של שפה מקומפלת.

אני לא מומחה ביישומי AI אבל גם בלי לכתוב יישומי AI קל להתחיל לכתוב ב Mojo ולהאיץ יישומי פייתון כמעט בלי מאמץ. בואו נראה איך זה עובד, אם זה באמת כל כך פשוט וכמה ביצועים נקבל ממעבר ל Mojo.

1. הניסוי: ספירת מספרים ראשוניים בפייתון

תוכנית הניסוי שבחרתי לא מסובכת. זה הקוד:

import time

LIMIT = 1_000_000


def is_prime(n: int) -> bool:
    if n < 2:
        return False
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    d = 3
    while d * d <= n:
        if n % d == 0:
            return False
        d += 2
    return True


def main():
    start = time.perf_counter()
    count = sum(is_prime(n) for n in range(1, LIMIT + 1))
    elapsed = time.perf_counter() - start
    print(f"Primes between 1 and {LIMIT:,}: {count:,}")
    print(f"Took {elapsed:.3f} s in pure Python")


if __name__ == "__main__":
    main()

התוכנית סופרת כמה מספרים ראשוניים יש עד מיליון ובודקת כמה זמן זה לקח. האלגוריתם לא יעיל בכוונה וריצה על המחשב שלי הסתיימה אחרי שניה וקצת:

ynonp@ynons-MacBook-Air ~/tmp/blog/mojodemo (main) $ uv run main_python.py
Primes between 1 and 1,000,000: 78,498
Took 1.341 s in pure Python

2. איך זה נראה ב Mojo

לפני שנלך לשלב את מוג'ו עם פייתון בואו נראה את אותו הקוד כתוכנית Mojo רגילה. את מוג'ו התקנתי עם uv לפי ההוראות מהאתר שלהם עם הפקודה:

uv add mojo --prerelease allow

ומיד לאחר מכן התקנתי את ה Agent Skill המתאים עם הפקודה:

npx skills add modular/skills

ביקשתי מקלוד לתרגם את הקוד ל mojo וזו התוצאה:

from std.time import perf_counter_ns

comptime LIMIT = 1_000_000


def is_prime(n: Int) -> Bool:
    if n < 2:
        return False
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    var d = 3
    while d * d <= n:
        if n % d == 0:
            return False
        d += 2
    return True


def main():
    var start = perf_counter_ns()
    var count = 0
    for n in range(1, LIMIT + 1):
        if is_prime(n):
            count += 1
    var elapsed = Float64(perf_counter_ns() - start) / 1e9
    print(t"Primes between 1 and {LIMIT}: {count}")
    print(t"Took {elapsed} s in pure Mojo")

ההבדל בפונקציה is_prime כמעט ולא מורגש - טיפוסי המשתנים ב mojo כתובים עם אות ראשונה גדולה והוספנו var בהצהרה על משתנים. פונקציית ה main של mojo פחות יפה מזו של פייתון, אין שם את ה sum וה List Comprehension ולפני מחרוזת עם משתנים הם רושמים t במקום f. לא משהו לקחת ללב במיוחד כשממילא יש סוכני AI שכותבים את זה.

זמני הריצה לעומת זאת זה סיפור אחר לגמרי:

Primes between 1 and 1000000: 78498
Took 0.02463 s in pure Mojo

במקום קצת יותר משניה אנחנו על 0.02 שניות. אבל שוב זה לא ממש כוחות כי אי אפשר להשוות שפת Interpreter כמו פייתון לשפה מקומפלת.

3. כח העל של מוג'ו: חיבור עם פייתון

אז איפה מתחיל הכיף? כח העל של Mojo הוא החיבור המובנה לפייתון. אפשר לכתוב קוד ב Mojo ולטעון אותו מפייתון, אפשר לטעון קוד פייתון מתוך קוד מוג'ו. בדוגמה של המספרים הראשוניים הניסוי השלישי להיום יהיה לקחת רק את הפונקציה שבודקת אם מספר הוא ראשוני ולכתוב אותה ב Mojo, תוך שאני שומר על הפונקציה main בפייתון, עם כל הרכבת הרשימות וה sum שאהבתי.

בשביל זה עליי לפצל את הקוד לשני קבצים. הקובץ main_mojo.py מכיל את פונקציית ה main:

import time

import mojo.importer  # noqa: F401  (enables importing .mojo modules)
from primes import is_prime

LIMIT = 1_000_000


def main():
    start = time.perf_counter()
    count = sum(is_prime(n) for n in range(1, LIMIT + 1))
    elapsed = time.perf_counter() - start
    print(f"Primes between 1 and {LIMIT:,}: {count:,}")
    print(f"Took {elapsed:.3f} s with Mojo is_prime")


if __name__ == "__main__":
    main()

קובץ זה מייבא את הפונקציה is_prime מהמודול primes - ופה ההפתעה הראשונה, במקום שיהיה לי קובץ primes.py יצרתי קובץ primes.mojo. זה תוכנו:

from std.os import abort
from std.python import PythonObject
from std.python.bindings import PythonModuleBuilder


@export
def PyInit_primes() abi("C") -> PythonObject:
    try:
        var m = PythonModuleBuilder("primes")
        m.def_function[is_prime]("is_prime")
        return m.finalize()
    except e:
        abort(String("failed to create module: ", e))


def is_prime(n_obj: PythonObject) raises -> PythonObject:
    var n = Int(py=n_obj)
    if n < 2:
        return PythonObject(False)
    if n < 4:
        return PythonObject(True)
    if n % 2 == 0:
        return PythonObject(False)
    var d = 3
    while d * d <= n:
        if n % d == 0:
            return PythonObject(False)
        d += 2
    return PythonObject(True)

יש פה את הפונקציה is_prime שאנחנו זוכרים מקודם אבל הפעם החתימה שלה שונה וגם המימוש. הפונקציה נקראת מתוך קוד פייתון ולכן הפרמטר שלה הוא מסוג PythonObject. היא גם עלולה לזרוק Exception וב Mojo עלינו להצהיר במפורש כשפונקציה עלולה לזרוק Exception, ובמקום להחזיר בוליאני היא מחזירה PythonObject כי אותו ערך יחזור לפייתון.

הקוד עצמו לוקח את המספר הפייתונאי והופך אותו למספר Int של Mojo, וגם בכל return הקוד עוטף את הערך הבוליאני של Mojo ב PythonObject כדי שפייתון תוכל להשתמש בערך.

החלק השני של הקוד הוא הגדרת המודול. ב Mojo עליי לאתחל את המודול ולשמור בו את כל הפונקציות שאני צריך. שוב קצת כאב ראש אבל לא משהו יותר מדי מאתגר, במיוחד כשממילא קלוד כותב את הקוד.

התוצאה כצפוי יושבת באמצע, יותר איטית ממוג'ו לבד אבל עדיין הרבה יותר מהירה מפייתון לבד:

ynonp@ynons-MacBook-Air ~/tmp/blog/mojodemo (main) $ uv run main_mojo.py
Primes between 1 and 1,000,000: 78,498
Took 0.071 s with Mojo is_prime

סך הכל אם כבר יש לכם יישומי פייתון ואתם מחפשים דרך קלה לשפר ביצועים באמצעות קומפילציה של פונקציות בודדות או חלקים מהתוכנית מוג'ו כבר יכולה לתת לכם כיוון טוב לשיפור. אם אתם יודעים פייתון ומחפשים שפת תכנות מעניינת ללמוד אז Mojo נראית מלהיבה, ואם אתם רוצים לבנות קוד שיבצע פעולות וקטוריות על GPU אז Mojo בכלל נראית כמו אופציה טובה בזכות השילוב של כל האקוסיסטם של פייתון יחד עם ביצועים של שפה מקומפלת.

העליתי לגיטהאב את הקוד של שלושת התוכניות עם כל קבצי הגדרת הפרויקט. מוזמנים להסתכל ולנסות להריץ אצלכם זה הקישור:

https://github.com/ynonp/mojodemo