社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python 现在可以运行 Mojo 了?

程序员好物馆 • 1 月前 • 139 次点击  


图片
作者 | Vincent      编译 | 苏宓
出品 | CSDN(ID:CSDNnews)

两年前,Swift 之父、编译器大神 Chris Lattner 和 Google 前员工 Tim Davis 组队创立了初创公司 Modular,推出了高性能编程语言 Mojo。凭借“比 Python 快 90000 倍”的惊人宣传语,Mojo 成为整个开发者社区关注的焦点,被认为是“可能彻底改变 Python 命运”的新语言。

Chris Lattner 曾这样描述 Mojo:“ 它是 Python 家族的一员,汲取了所有这些酷炫的语言、编译器和其他技术,让 Python 向前迈进了一大步。我们认为它增强了 Python 的能力,赋予 Python 程序员超能力,让熟悉 Python 的人能够学习新知识,探索并征服新领域,而无需转用 C++。”

而如今,Chris Lattner 低调放出了一个意味深长的新变化:Python 现在可以直接调用 Mojo 代码了。

Mojo 正在被 Python 调用

据开发者 Vincent D. Warmerdam 的实测,Python 调用 Mojo 现在变得非常简单,详细步骤如下。

首先,可以直接用 uv 安装:

uv pip install modular --index-url https://dl.modular.com/public/nightly/python/simple/

然后你可以创建一个 .mojo 文件,导出一个计算阶乘的函数 factorial(),内容如下:

# mojo_module.mojofrom python import PythonObjectfrom python.bindings import PythonModuleBuilderimport mathfrom os import abort@exportfn PyInit_mojo_module() -> PythonObject:    try:        var m = PythonModuleBuilder("mojo_module")        m.def_function[factorial]("factorial", docstring="Compute n!")        return m.finalize()    except e:        return abort[PythonObject](String("error creating Python Mojo module:", e))fn factorial(py_obj: PythonObject) raises -> PythonObject:    var n = Int(py_obj)    var result = 1    for i in range(1, n + 1):        result *= i    return result

然后你就可以在 Python 中加载它:

# main.pyimport max.mojo.importerimport osimport sysimport time import mathsys.path.insert(0"")import mojo_modulestart = time.time()print(mojo_module.factorial(10))end = time.time()print(f"Time taken: {end - start} seconds for mojo")start = time.time()print(math.factorial(10))end = time.time()print(f"Time taken: {end - start} seconds for python")

运行结果如下:

3628800Time taken: 3.0279159545898438e-05 seconds for mojo3628800Time taken: 5.0067901611328125e-06 seconds for python

一切运行正常。

问题显现

不过,在实测时,Vincent 也注意到了一些问题,对于 factorial(10) 这样的轻量计算,Mojo 与 Python 本身速度相差无几。但当输入扩大到 factorial(100) 时,Mojo 返回的结果却是错误的(输出为 0),而 Python 的结果则是正确的。

0


    
Time taken: 2.7894973754882812e-05 seconds for mojo188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000Time taken: 9.298324584960938e-06 seconds for python

这可能是 Mojo 侧溢出的结果。文档也提到这整套系统还处于早期阶段,说明其数值系统尚不成熟。

另一个例子

考虑到上面的问题可能是溢出引起的,Vincent 又试了一个例子来看看能不能测出加速效果。这次是一个朴素的素数统计实现。Mojo 代码如下:

from python import PythonObjectfrom python.bindings import PythonModuleBuilderimport mathfrom os import abort@exportfn PyInit_mojo_module() -> PythonObject:    try:        var m = PythonModuleBuilder("mojo_module")        m.def_function[count_primes]("count_primes", docstring="Count primes up to n")        return m.finalize()    except e:        return abort[PythonObject](String("error creating Python Mojo module:", e))fn count_primes(py_obj: PythonObject) raises -> PythonObject:    var n = Int(py_obj)    var count: Int = 0    for i in range(2, n + 1):        var is_prime: Bool = True        for j in range(2, i):            if i % j == 0:                is_prime = False                break        if is_prime:            count += 1    return count

对应的 Python 测试代码如下,此外 Vincent 还加了一个 NumPy 实现做对比:

import numpy as npimport max.mojo.importerimport osimport sysimport time import mathsys.path.insert(0"")import mojo_moduledef count_primes(n):    count = 0    for i in range(2, n + 1):        is_prime = True        for j in range(2, i):            if i % j == 0:                is_prime = False                break        if is_prime:            count += 1    return countdef count_primes_numpy(n):    if n 2:        return 0    candidates = np.arange(2, n + 1)    is_prime_mask = np.ones(len(candidates), dtype=bool)


    
    for idx, candidate in enumerate(candidates):        if candidate == 2:            continue        divisors = np.arange(2, candidate)        has_divisor = np.any(candidate % divisors == 0)        if has_divisor:            is_prime_mask[idx] = False    return np.sum(is_prime_mask)n = 20_000start = time.time()print(count_primes(n))end = time.time()print(f"Time taken: {end - start} seconds for python")start = time.time()print(count_primes_numpy(n))end = time.time()print(f"Time taken: {end - start} seconds for numpy")start = time.time()print(mojo_module.count_primes(n))end = time.time()print(f"Time taken: {end - start} seconds for mojo")

运行结果如下:

  • Python 原生实现耗时:约 0.45 秒

  • NumPy 实现耗时:约 0.26 秒

  • Mojo 实现耗时:仅 0.01 秒

2262Time taken: 0.44585609436035156 seconds for python2262Time taken: 0.25995898246765137 seconds for numpy2262Time taken: 0.011101961135864258 seconds for mojo

尽管这一 benchmark 并非最优算法,但结果仍然具备参考价值:在这种纯 CPU 密集型的计算任务中,Mojo 的性能提升确实相当明显,尤其是与 NumPy 相比也有数量级上的优势。

写在最后

整体而言,通过实测,Vincent 发现,Mojo 的语法风格延续了 Python 的简洁性,同时具备编译语言的性能与类型系统。

不过,Mojo 当前仍处于早期阶段。文档覆盖不全、标准库功能有限、整套开发体验尚不稳定……这也意味着距离“生产可用”还有距离。

但从 Modular 的近期动作可以看出,该团队正在有意识地为 Python 社区打造“融合路径”——不是简单地“替代 Python”,而是围绕其生态做加速和增强。这种“拥抱兼容”的姿态或许更务实,也更容易获得社区的接纳。

对此,Vincent 评价道,「现在还不能称得上“生产可用”,但我已经更有信心了 —— 梦想确实正在靠近。

原文:https://koaning.io/posts/giving-mojo-a-spin/

图片
好啦,今天的内容分享就到这,感觉不错的同学记得分享点赞哦!
PS:程序员好物馆 持续分享程序员学习、面试相关干货,不见不散!
图片
点分享
图片
点收藏
图片
点点赞
图片
点在看

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/183647
 
139 次点击