本文经授权转自公众号优快云(ID:优快云news)
作者 | Vincent,编译 | 苏宓
👇我的小册 45章教程:(小白零基础用Python量化股票分析小册) ,原价299,限时特价2杯咖啡,满100人涨10元。
👇我的小册 AI工具100个实战小案例:(100个AI工具实战小案例) ,原价299,限时早鸟价29,满100人涨10元。
两年前,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 代码了。
1、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
一切运行正常。
2、问题显现
不过,在实测时,Vincent 也注意到了一些问题,对于 factorial(10) 这样的轻量计算,Mojo 与 Python 本身速度相差无几。但当输入扩大到 factorial(100) 时,Mojo 返回的结果却是错误的(输出为 0),而 Python 的结果则是正确的。
0Time taken: 2.7894973754882812e-05 seconds for mojo188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000Time taken: 9.298324584960938e-06 seconds for python
这可能是 Mojo 侧溢出的结果。文档也提到这整套系统还处于早期阶段,说明其数值系统尚不成熟。
3、另一个例子
考虑到上面的问题可能是溢出引起的,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 相比也有数量级上的优势。
4、写在最后
整体而言,通过实测,Vincent 发现,Mojo 的语法风格延续了 Python 的简洁性,同时具备编译语言的性能与类型系统。
不过,Mojo 当前仍处于早期阶段。文档覆盖不全、标准库功能有限、整套开发体验尚不稳定……这也意味着距离“生产可用”还有距离。
但从 Modular 的近期动作可以看出,该团队正在有意识地为 Python 社区打造“融合路径”——不是简单地“替代 Python”,而是围绕其生态做加速和增强。这种“拥抱兼容”的姿态或许更务实,也更容易获得社区的接纳。
对此,Vincent 评价道,「现在还不能称得上“生产可用”,但我已经更有信心了 —— 梦想确实正在靠近。」
原文:https://koaning.io/posts/giving-mojo-a-spin/
本文转自公众号“优快云”,ID:优快云news
最后推荐一下我们团队写的量化小册的内容,48篇内容!从Python安装,入门,数据分析,爬取股票基金的历史+实时数据,以及如何写一个简单量化策略,策略回测,如何看资金曲线统统都有介绍!非常超值!
欢迎订阅:原价299 早鸟价2杯咖啡钱,即可永久阅读。现在的价格非常非常低,只要2杯奶茶,就可以终身订阅+课程源码,还有永久陪伴群。48小时无理由退款,放心食用!
往期推荐
量化: 如何用Python爬取创业板历史+实时股票数据!|实战股票分析篇利用Pandas 9招挖掘五粮液股价!|实战股票数据分析篇 Pandas滚动操作 |量化股票第一步,用Python画股票K线,双均线图,可视化你的股票数据!|如何用Python爬取全部800多只ETF基金数据!|如何用Python写一个双均线策略 |如何用Python开发一个多策略机器人!上篇!|Python量化系列-用布林策略买五粮液能赚多少钱?|只要4秒钟!用Python 获取上证指数34年的历史日线数据!