跳转到主要内容

CPython的JIT编译器包装器

项目描述

Pyjion logo

Pyjion,一个为CPython编译Python代码到本地CIL并使用.NET 7 CLR执行的JIT扩展。

Documentation Status PyPI Downloads

您现在可以在 live.trypyjion.com 测试Pyjion。

pyjion.readthedocs.io 阅读完整文档。

安装

$ pip install pyjion

从源码编译

先决条件

  • CPython 3.10
  • CMake 3.13 +
  • .NET 7
  • scikit-build
 $ git clone git@github.com:tonybaloney/pyjion --recurse-submodules
 $ cd pyjion
 $ python -m pip install .

使用Pyjion

要开始,您需要安装.NET,Python 3.10和Pyjion包(我也推荐使用虚拟环境)。

导入pyjion后,通过调用 pyjion.enable() 启用它,这会将编译阈值设置为0(代码只需运行一次即可由JIT编译)

>>> import pyjion
>>> pyjion.enable()

您定义或导入的任何Python代码在启用pyjion后都将进行JIT编译。您不需要在特殊API中执行函数,它完全透明

>>> def half(x):
...    return x/2
>>> half(2)
1.0

Pyjion将half函数即时编译成机器代码,并在函数对象内部存储编译函数的缓存版本。您可以通过运行 pyjion.info(f) 来查看一些基本统计信息,其中 f 是函数对象

>>> pyjion.info(half)
JitInfo(failed=False, compile_result=<CompilationResult.Success: 1>, compiled=True, optimizations=<OptimizationFlags.InlineFramePushPop|InlineDecref: 10>, pgc=1, run_count=1)

您还可以针对任何脚本或模块执行Pyjion

pyjion my_script.py

或者,对于现有的Python模块

pyjion -m calendar

优化级别

Pyjion有3个优化级别,0是最低的,2是最高的。默认情况下,Pyjion将在级别1编译。

可以使用config()函数更改此级别

pyjion.config(level=2)

在运行完1级代码和测试后,尝试2级以比较性能。如果遇到问题,请尝试降低级别。

故障排除

PGC 解包错误

如果在运行代码时遇到 pyjion.PyjionUnboxingError,这意味着 Pyjion 优化了一个包含浮点数、整数或布尔值的函数,但在后续调用中这些类型已改变。为了避免这种情况,您可以禁用 PGC (pyjion.config(pgc=False))或降低优化级别。这两种选项都会影响整体性能,所以如果可能,请重构函数,使其不执行混合类型的通用操作。

反汇编

您可以通过在 Python REPL 中反汇编编译后的函数来查看编译函数的机器代码。Pyjion 实际上已将您的小 Python 函数编译成一个小型独立应用程序。首先安装 distorm3rich 以反汇编 x86-64 代码,然后运行 pyjion.dis.dis_native(f)

>>> import pyjion.dis
>>> pyjion.dis.dis_native(half)
00000000: PUSH RBP
00000001: MOV RBP, RSP
00000004: PUSH R14
00000006: PUSH RBX
00000007: MOV RBX, RSI
0000000a: MOV R14, [RDI+0x40]
0000000e: CALL 0x1b34
00000013: CMP DWORD [RAX+0x30], 0x0
00000017: JZ 0x31
00000019: CMP QWORD [RAX+0x40], 0x0
0000001e: JZ 0x31
00000020: MOV RDI, RAX
00000023: MOV RSI, RBX
00000026: XOR EDX, EDX
00000028: POP RBX
00000029: POP R14
...

将可移植指令集转换为低级机器指令的复杂逻辑是由 .NET 的 CLR JIT 编译器完成的。

启用 JIT 后,所有执行的 Python 代码都将编译成原生机器代码并在运行时缓存到磁盘上。例如,要为 Flask 网络应用程序中的简单 app.py 启用 JIT

from src import pyjion
pyjion.enable()

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

app.run()

常见问题解答

“Pyjion”怎么读?

像“鸽子”这个词一样。@DinoV 想要一个既有“Python” -- “Py”部分 -- 又有“JIT” -- “JI”部分 -- 的名字,并且要能发音。

这与其他产品相比如何?

PyPy?

PyPy 是一个具有自己 JIT 的 Python 实现。与 Pyjion 相比,PyPy 除非使用 CFFI 或与 PyPy 支持的 CPython C API 的子集一起工作,否则不支持所有 C 扩展模块。Pyjion 旨在支持许多 JIT 编译器,而 PyPy 只支持它们的自定义 JIT 编译器。

Pyston?

Pyston 是一个使用 LLVM 作为 JIT 编译器的 Python 实现。与 Pyjion 相比,Pyston 具有部分 CPython C API 支持,但不是完整的支持。Pyston 也只支持 LLVM 作为 JIT 编译器。

Numba?

Numba 是一个针对“数组导向和数学密集型 Python 代码”的 JIT 编译器。这意味着 Numba 专注于科学计算,而 Pyjion 则试图优化所有 Python 代码。Numba 也只支持 LLVM。

IronPython?

IronPython 是一个使用 .NET 实现的 Python。虽然 IronPython 尝试在 .NET 中使用,但 Pyjion 与 .NET 不兼容。这也意味着 IronPython 不能使用 C 扩展模块,而 Pyjion 可以。

Psyco?

Psyco 是一个猴子补丁 CPython 以添加自定义 JIT 编译器的模块。Pyjion 希望为添加 JIT 编译器到 CPython 引入一个合适的 C API,而不是猴子补丁。需要注意的是,Psyco 的创建者后来成为 PyPy 的共同创始人之一。

Unladen Swallow?

Unladen Swallow 是一个尝试使 LLVM 成为 CPython JIT 编译器的项目。不幸的是,在花费大量时间修复 LLVM JIT 编译器(该编译器在随后的几年中得到了大幅改进)的问题之前,该项目在完成工作前就失去了资金。

NuitkaShedskin

Both Nuitka and Shedskin are Python-to-C++ transpilers,这意味着它们将Python代码转换为等效的C++代码。作为JIT,Pyjion不是一个transpiler。

它是否会与CPython一起发布?

目标#1是明确地向CPython添加一个C API以支持JIT编译器。然而,并没有期望将JIT编译器与CPython一起发布。这是因为CPython仅使用C89编译器进行编译,这使得它能够在许多平台上运行。但是,如果将JIT编译器添加到CPython,它将立即限制只支持JIT所支持的平台。

这有助于使用CPython与.NET或UWP吗?

不。如果你想要Python和.NET 4的集成,请使用Python.NET

行为准则

本项目采用了Microsoft Open Source Code of Conduct。有关更多信息,请参阅行为准则FAQ或联系opencode@microsoft.com提出任何额外的问题或评论。

发行说明

2.0.0

  • 更新到.NET 7

1.2.7

  • 修复了原生x86_64反汇编器中的错误,该错误关于Windows Intel CPU的兼容性问题

1.2.6

  • 扩展了RelWithDebInfo模式下的优化

1.2.5

  • pyjion.config(debug=)设置更改为允许True或False(如之前),或0(发布),1(调试),2(发布WithDebugInfo)

1.2.4

  • 更新到rich 11.0
  • 修复了CIL反汇编器中关于常量double(LDC_R8)操作码的错误

1.2.3

  • 未装箱操作不会更新帧的最后一个指令,因为它们无法引发异常(使它们更快)

1.2.2

  • 添加了pyjion.dis.flow_graph()函数,用于获取CIL基本块的DOT控制流图
  • 添加了pyjion.dis.cil_instructions()函数,用于从编译函数获取CIL指令列表
  • 为Windows启用ASAN(编译时选项)
  • 当目标在1个字节内时,CIL编译为短分支操作码
  • 在CIL反汇编输出中显示有效的分支目标

1.2.1

  • 修复了OPT-12(方法缓存)中的错误,它会存储全局子类的错误缓存地址。SQLalchemy中发现了此错误。

1.2.0

  • 当函数以与优化时不同的参数类型调用时,可以避免PGC解装箱错误。
  • PGC类型现在将在跳转语句、for循环和其他小范围内推断,从而提高性能
  • LOAD_METHOD将使用内置类型(如dictlist等)的缓存指针,这意味着在许多情况下LOAD_METHOD更快
  • 字典合并运算符||=将断言返回类型为dict
  • 修复了在Windows上引用已释放模块的调用点或序列点时的崩溃问题
  • 修复了带有参数的pyjion -m module运行时的问题

1.1.1

  • 修复了一个关键错误,其中递归函数使用可变容器类型(例如列表)会导致对错误对象的递减引用并随后崩溃。
  • 修复了递归函数图生成中的错误,在某些情况下导致崩溃
  • 修复了方法调用中的错误,当类使用copy.copy()复制时,它会调用错误的方法。
  • 减少了方法调用时的内存消耗

1.1.0

  • 为BINARY_LSHIFT、BINARY_RSHIFT、BINARY_AND、BINARY_OR、BINARY_XOR添加了未装箱整数操作
  • 如果右侧操作数是一个不会溢出的常量(例如x ** 2),则BINARY_MULTIPLY和BINARY_POWER将保持未装箱
  • 为float、bool和int类型添加了未装箱的UNARY_NOT、UNARY_POSITIVE和UNARY_NEGATIVE操作
  • 为int和bool类型添加了未装箱的UNARY_INVERT操作
  • 为bytearrays添加了未装箱的STORE_SUBSCR
  • 全局变量的类型在编译时进行配置
  • 通过添加未装箱的字节数组类型和字节数组的未装箱切片操作,提高了字节数组的性能,从而产生未装箱的整数
  • 修复了与未装箱范围迭代器相关的引用计数错误
  • PGC 现在允许将值 0 或 1 的 int 未装箱到 bool
  • 整数的未装箱现在更高效,并且允许将 True 未装箱到 1,将 False 未装箱到 0

1.0.0

  • 修复了当使用无效参数调用 pyjion.config() 时崩溃的错误 (#401)
  • 更新到 .NET 6 GA
  • 当编译后全局变量或内置函数未更改时,LOAD_GLOBAL 运行更快,通过缓存对象地址。
  • 现在通过向量调用 (faster) 将对 Python 函数的调用路由
  • 调用内置类型(如 int()、str() 等)的性能得到提高
  • C函数的调用更快
  • 将乐观整数优化添加到第 2 级,以检查整数值并在它们较小时进行未装箱
  • 抽象值分析器将根据值断言常量值的元组(例如 float、int)
  • 当启用优化 AttrTypeTable (第 1 级) 时,LOAD_ATTR 会通过缓存的属性查找表推断类的属性类型
  • 修复了一个错误,该错误会在调用 pyjion.enable() 时将优化级别重置为 1
  • 修复了一个错误,该错误会导致在大型函数中发生的大范围跳转导致无效跳转操作和编译失败

1.0.0 (rc4)

  • 为 Apple macOS (M1 Silicon) 添加了 ARM64 支持。JIT 将生成原生 ARM64 汇编。不支持反汇编。
  • 添加了 Linux/ARM64 支持和 manylinux 轮
  • 添加了 Windows/ARM64 支持
  • 现在所有 JIT 配置都通过 pyjion.config() 函数设置,而不是 enable_feature()/disable_feature()
  • 修复了当函数编译时未启用图形化会导致 pyjion.graph() 引发异常的错误
  • 添加了对 SETUP_ANNOTATIONS 操作码的支持
  • 添加了对 3.10 生成器的支持
  • 修复了 DUP_TOP_TWO 操作码中的逃逸变量的错误
  • UNPACK_SEQUENCE 现在会为常量字符串、int 和 float 元组生成类型
  • STORE_FAST 现在在 PGC 的探测阶段进行评估,导致在可以使用未装箱的 int 和 float 的许多情况下性能显著提高
  • 添加了一个简单的基准测试脚本 (Tests/benchmarks/suite.py)
  • 将 scikit-build 升级到 0.12 以支持本机 VS2019

1.0.0 (rc3)

  • 更新到 .NET 6 RC1
  • 添加了 Python 3.10 支持
  • 实验性的 try..except 语句、堆栈异常处理程序和异常过滤。默认禁用
  • 修复了 LOAD_METHOD 无法立即抛出异常的错误,因为无法解析该方法
  • 在 3.10 构建中删除了 enable_tracing()enable_profiling 函数。分析和跟踪在编译时检测,并通过 .info() 方法提供
  • 添加了对 PEP626(快速行跟踪)的支持
  • 扩展了对 CFunction 调用的分析支持
  • PyTrace_RETURN 现在将返回值作为参数正确发送,符合 CPython 规范
  • 修复了范围迭代器逃逸时导致 SEG 的错误

1.0.0 (rc2)

  • BINARY_MULTIPLY 和 BINARY_POWER 将假设结果整数是大整数(未装箱)
  • 引入了两个优化 IntegerUnboxingMultiply 和 IntegerUnboxingPower,它们在优化级别 2 上应用。如果您使用整数,请尝试第 2 级,但请以较小的值尝试以获得更好的性能。
  • Pyjion 将推断 range(n) 生成整数迭代器以改进未装箱
  • LOAD_BUILD_CLASS 将推断函数类型而不是 Any (#42)
  • 指令图将包括快速局部变量的名称
  • 指令图常量值限制为 40 个字符
  • 为所有内置函数添加了抽象类型(#339)
  • pyjion.info() 现在将返回一个 JitInfo 对象
  • 在编译过程中应用于函数的优化标志现在可在 JitInfo.optimizations 中获取
  • 所有优化现在都是运行时标志,而不是编译时功能
  • 解箱 PGC 错误将引发 pyjion.PyjionUnboxingError(ValueError)而不是 ValueError
  • 指令图将显示条件分支(橙色)
  • 修复了生成器中的错误,其中混合解箱/装箱快速局部变量会在第一个和第二个编译阶段之间产生错误值
  • 修复了由于 PGC 在分析阶段断言抽象类型,然后总是断言整数是大整数而在 rc1 中发生的去优化问题
  • 修复了在 yield 时解箱局部变量会减少帧局部变量的错误
  • 出于稳定性原因,生成器将不会解箱快速局部变量
  • 修复了解箱整数回归,这是由于 PGC 值被设置为 Any 所致
  • 断言浮点对象方法(as_integer_ratio、conjugate、is_integer、hex)的返回类型

1.0.0(rc1)

  • 添加了 pyjion 命令行脚本来补充 python -m pyjion 命令
  • pyjion CLI 有用于启用分析、跟踪、优化级别、图和调试的标志
  • 无法放入 long long 的解箱整数将引发 ValueError。
  • Pyjion 将任何大于 10 亿的值标记为“大整数”,并避免将其逃逸,以减少溢出的可能性。
  • 浮点数 __pow__ 与负值的行为与 CPython 相同
  • 0 提到负数次幂将引发 ZeroDivisionError
  • PGC 现在不再使用对探测值的引用,大大减少了第一和第二次编译周期之间的内存消耗
  • 修复了由于在分数算术中引发溢出而导致 statistics.variance([0, 0, 1]) 会引发断言错误的错误(#326)
  • 修复了调用 sys.settrace(None) 会造成段错误的错误(#330)
  • 修复了优化调用自定义类型时在第三次执行时崩溃的错误,这是由于 PGC 持有和释放引用的方式所致。
  • 将 Pyjion 的测试套件重构为 Pytest
  • 重写了文档网站
  • 修复了原生反汇编器打印空注释行的错误
  • 更正了 pyjion.get_offsets() 的类型签名
  • 修复了由于加载方法优化方式导致的对象(如全局)更改方法时引起崩溃的错误(#335)

1.0.0(beta7)

  • 添加了 pyjion.symbols(callable) API 来获取外部调用标记的字典
  • 扩展了 dis()dis_native() 方法,添加了一个标志来不打印程序计数器(print_pc=False
  • 改进了 dis_native() 方法,以便在 call 指令后作为行注释打印方法调用名称
  • 修复了 dis_native() 中的错误,该错误在打印输出顶部显示了未解决的序列点
  • 修复了在 in(CONTAINS_OP)操作结果未检查异常的情况下,如果 in 操作返回错误结果,则下一个操作会段错误的错误。
  • dis() 中的 IL 与 Ildasm 的语法更接近,更容易阅读
  • 添加了 pyjion.status() 方法以获取 JIT 的运行时数据
  • Windows 现在将观察 DOTNET_ROOTDOTNET_LIB_PATH 环境变量

1.0.0(beta6)

  • 更新到 .NET 6 预览版 6
  • 修复了 ord() 内置函数返回错误类型的问题(#315)
  • pyjion.dis.dis()pyjion.dis.dis_native() 将将序列点显示为注释
  • 二进制幂和就地幂操作码始终返回原生Python长整型,而不是转义整型,以避免溢出

1.0.0 (beta5)

  • 修复了大型字典字面量(>100个键)的bug
  • 提高了BUILD_TUPLE、BUILD_LIST、BUILD_CONST_KEY_MAP和BUILD_SET操作码的效率
  • 修复了比较numpy数组时未装箱为布尔数组而是保持为数组的bug (#310)

1.0.0 (beta4)

  • 支持yield关键字和Python生成器

1.0.0 (beta3)

  • 可以使用pyjion.enable_graphs()启用指令图,然后通过pyjion.get_graph(f)导出
  • 如果.NET缺失,Pyjion将引发ImportError而不是系统退出

1.0.0 (beta2)

  • 快速局部变量可以存储非装箱值
  • 通过断言返回类型对已知类型进行方法调用优化,例如str.upper()返回字符串
  • 更新到.NET 6预览版5
  • 可以使用python -m pyjion <command>运行Pyjion,例如python -m pyjion script.pypython -m pyjion -m unittest

1.0.0 (beta1)

  • 添加了对整数的非装箱支持(OPT-16)
  • 添加了对bool的非装箱支持
  • 修复了Windows上内部化哈希表的bug

1.0.0 (alpha4)

  • 为浮点对象添加了非装箱和逃逸分析(OPT-16)
  • 移除OPT-8,因为它已被OPT-16取代

1.0.0 (alpha3)

  • 更新到.NET 6预览版4

1.0.0 (alpha2)

  • 可以使用pyjion.enable_debug()/pyjion.disable_debug()在运行时切换可调试的JIT方法
  • 添加了在pyjion.dis.dis()pyjion.dis.dis_native()的Pyjion反汇编打印输出中包含Python字节码反汇编的选项
  • 添加了API pyjion.get_offsets(callable)以获取Python操作码<> IL偏移<>原生偏移。
  • 将内部表示移动到固定宽度标准类型。

1.0.0 (alpha1)

  • Pyjion使用.NET 6预览版3作为编译器,对于Linux和macOS,请确保您已首先安装它
  • 浮点数的丰富比较(==、<、>)速度显著提高(OPT-17)
  • 通过强制执行vectorcall协议和在10个以下参数的情况下内联一切来提高所有方法调用的速度(OPT-16)

0.15.0

  • PGC现在观察并优化堆分配的(用户定义的)类型
  • 修复了启用PGC时某些递归函数的崩溃问题

0.14.1

  • 修复了macOS轮的名称

0.14.0

  • 对于实现tp_getattr的类型,现在通过预哈希名称优化了LOAD_ATTR(OPT-15)
  • JIT现在会直接调用LOAD_ATTR tp_getattro/tp_getattr内置类型的槽
  • macOS轮现在使用Clang PGO编译
  • PGC只会为非堆分配的类型(即非用户指定的类型)进行配置文件生成,因为类型对象可能在编译周期之间被回收
  • 在帧调用/函数调用期间减少了堆栈效果
  • 提高了函数调用的性能
  • Py_MakePendingCalls将在每100条指令后调用一次(以前是10次),在编译时通过EMIT_PENDING_CALL_COUNTER定义可配置
  • 更新到.NET 5.0.5(5.0.202)
  • 修复了PGC的大函数bug,这意味着它们不会被优化
  • 为BINARY_SUBSCR实现了PGC(OPT-5)
  • 为STORE_SUBSCR实现了PGC(OPT-6)
  • 为所有就地和常规二元运算符(+、-、/等)实现了PGC,请参阅OPT-13

0.13.0

  • 如果.NET发出FAST_FAIL辅助函数,则编译器将失败(并默认回退到CPython)
  • UNPACK_SEQUENCE现在被重写以更高效,并使用针对LIST和TUPLE类型的优化路径
  • f-string(BUILD_STRING)现在被重写以更高效
  • UNPACK_EX现在被重写以移除对动态堆分配的要求(以及堆栈的哨兵),并利用.NET编译器的动态评估堆栈
  • 为UNPACK_SEQUENCE实现了PGC
  • 为BINARY_SUBSCR实现了PGC
  • 为CALL_FUNCTION/OPT-14实现了PGC

0.12.0

  • 将PGC发射器添加到第一个编译遍历
  • 大幅度简化了编译过程,导致调用栈变小,允许进行更多递归(并提高性能)
  • 向pyjion.info()字典中添加了一个字段compile_result,表示编译失败的原因(如果失败),请参见AbstractInterpreterResult以获取枚举
  • 修复了pyjion.dump_native/pyjion.dis.dis_native反汇编包装函数中的错误
  • 在编译过程早期将不兼容的函数(包含async、yield关键字)标记为不兼容
  • 修复了在特定情况下类型改变时OPT-13的错误
  • 帧的参数现在被标记为易变,并且对于某些优化需要类型保护
  • 现在任何作为参数传递的Python类型都可以由OPT-13、OPT-12进行优化
  • 修复了在Linux和Windows上sre_parse._compile的错误,该错误在执行内联decref操作时会导致GuardStackException。
  • 添加了环境变量DOTNET_LIB_PATH,允许指定libclrjit的确切路径

0.11.0

  • 添加了OPT-13(OPTIMIZE_TYPESLOT_LOOKUPS)以优化所有二元操作的类型槽,并在编译时解决优先级(仅针对已知类型)
  • 添加了OPT-14(OPTIMIZE_FUNCTION_CALLS)以优化对内置函数的调用
  • 通过在编译时确定抽象类型来优化所有帧局部变量
  • 错误修复:修复了具有大量(>255)参数的f-string崩溃问题
  • 错误修复:现在将跳过包含exec()使用的所有函数,因为它包含不受支持的帧全局变量
  • 更新到.NET 5.0.3
  • 将容器更新到Ubuntu 20
  • 添加了fileobject抽象类型
  • 添加了enumerator抽象类型
  • 添加了codeobject抽象类型
  • 为所有二元操作添加了集成测试,以检查引用泄漏(感谢@amaeckelberghe)
  • 添加了module类型(感谢@vacowboy75)

0.10.0

  • 添加了OPT-12(OPTIMIZE_BUILTIN_METHOD)以预查找内置类型的函数并绕过LOAD_METHOD(PyObject_GetMethod)
  • 优化了LOAD_METHOD,以回收对同一对象的查找
  • 扩展了OPT-8、OPT-9、OPT-11、OPT-12以支持嵌套堆栈(例如表达式内部)
  • 添加了frozenset抽象类型

0.9.0

  • 添加了OPT-11(OPTIMIZE_BINARY_SLICE)以在切片开始、结束和步长为None或常数值时将BUILD_SLICE和BINARY_SUBSCR操作优化为单个函数。
  • 修复了set_optimization_level()重置的错误(感谢@tetsuo-cpp)
  • 添加了bytearray抽象值类型(感谢@tetsuo-cpp)
  • 添加了type抽象值类型(感谢@tetsuo-cpp)
  • 优化了编译指令,仅在错误/退出分支上更新帧的最后一条指令字段
  • 删除了每个for/while循环都调用的“周期性工作”方法,并每10次循环调用一次Py_MakePendingCalls的功能
  • 在过程阶段添加了对内置类型方法的返回值抽象类型的推断改进,例如str.encode
  • 在dis_native中添加了对编译函数未编译情况的检查(感谢@tetsuo-cpp)
  • 当安装了rich包时,dis_native将漂亮地打印汇编代码(感谢@C4ptainCrunch)
  • pyjion[dis]是pystorm3和rich捆绑的新包(感谢@C4ptainCrunch)

0.8.0

  • 使用新的抽象类型iterable、bytearray、codeobject、frozenset、enumerator、file、type和module增强了编译器的过程阶段
  • 过程阶段将断言对任何内置函数的调用(例如list()、tuple())的抽象返回类型,这将针对更广泛的场景启动优化
  • 添加了OPT-8(OPTIMIZE_BINARY_FUNCTIONS)以将两个连续的二元操作合并为一个操作。在PyFloat操作中增加了约15-20%的性能提升。
  • 添加了OPT-9(OPTIMIZE_ITERATORS)以将列表迭代器(List iterator)的FOR_ITER操作码内联到本地汇编指令中。
  • 添加了OPT-10(OPTIMIZE_HASHED_NAMES)以预先计算LOAD_NAME和LOAD_GLOBAL字典查找的哈希值
  • 修复了查找字典对象的已知哈希值(优化BINARY_SUBSCR)不会引发KeyError的错误。在#157中看到。

0.7.0

  • 修复了JUMP_IF_FALSE_OR_POP/JUMP_IF_TRUE_OR_POP操作码中导致栈增长的错误,这会导致后续分支检查时栈下溢。JIT现在可以编译更广泛的功能。
  • 实现了PEP590向量化调用,用于具有10个以上参数的方法(感谢 @tetsuo-cpp)。
  • 实现了PEP590向量化调用,用于具有10个以上参数的函数。
  • 修复了在具有大量参数的方法调用中出现的引用泄漏。
  • 支持对具有10个以上参数的函数调用进行跟踪。
  • 禁用OPT-4,因为它会导致引用泄漏。

0.6.0

  • 添加了OPT-6优化。现在使用帧常量来加速对列表和字典的赋值。如果某物是列表或字典,STORE_SUBSCR将断言并简化赋值逻辑。
  • 添加了OPT-7优化。在一系列情况下,二进制下标运算符被编译为更快的路径,特别是如果索引/键是帧常量。哈希值在编译时预先计算,整型常量的索引转换为本地数字。
  • 本机机器码反汇编器将显示JIT代码在内存中的实际位置,而不是从偏移量0开始。
  • 函数pyjion.dump_native()返回一个包含字节、长度和位置的元组。
  • 对所有内联和二进制操作进行了类型推断改进。
  • 修复了从源码构建Windows版本的问题,当用户想要针对.NET的签出编译时。
  • 实现了针对额外操作码的FAST_DISPATCH。
  • 添加了一个用于测试CPython回归套件的测试运行器,该套件可以单独测试JIT。
  • 修复了LOAD_METHOD操作码的(self)引用泄漏。
  • 修复了通过Call (CALL_FUNCTION)调用非C函数时出现的引用泄漏。
  • 修复了通过BUILD_TUPLE操作码创建(非常)大元组时导致的溢出错误。
  • 修复了调用BUILD_MAP操作码时,使用非常大的字典导致的致命错误。

0.5.0

  • 添加了OPT-4优化。使用LOAD_FAST、STORE_FAST和DELETE_FAST操作码的帧本地(编译时已知的命名变量)将使用本地.NET本地变量,而不是使用帧的f_localsplus数组。
  • 通过OPT-4改进了LOAD_FAST和STORE_FAST的性能。
  • 添加了OPT-5优化。现在入口/退出时的帧推/弹出是内联CIL指令。
  • LOAD_FAST在STORE_FAST之后跳过未绑定本地检查(即槽位肯定已分配)。

0.4.0

  • 修复了CPython从ceval状态检查递归深度时出现的崩溃错误,该状态可能未设置。
  • 实现了一个更快的递归深度检查。
  • 修复了LOAD_CLOSURE操作符未设置的错误。
  • 修复了Windows和Linux上的OPT-2。
  • 修复了使用错误的CIL操作码进行减法时抛出溢出错误并回退到EFD的错误。
  • 实现了.NET EE异常处理程序,用于保护栈的哨兵、溢出错误和空引用异常。
  • 实现了ld_i(1)的更有效版本。
  • 将ob_refcnt的案例更正为使用64位有符号整数。
  • 不再在发布代码上打印未实现的.NET EE方法错误消息。
  • 修复了设置错误的vtable相对字段的问题。
  • 修复了即使没有明确启用,也会发出跟踪和配置文件错误的问题。
  • 在运行时将.NET异常转换为Python异常。

0.3.0

  • 添加了优化(OPT-1/OPTIMIZE_IS),将"是"/"不是"语句内联为简单的指针比较与跳转语句。编译为内联机器代码而不是方法调用。
  • 添加了优化(OPT-2/OPTIMIZE_DECREF),在对象引用计数大于1时,不通过方法调用递减引用计数,然后当引用计数变为0时调用_Py_dealloc。替换了之前的方法调用。
  • Windows现在使用系统页面大小而不是默认的1MB值。

0.2.1

  • 添加了对.NET 5.0.1的支持。
  • 实现了CIL模数发射器。

0.2.0

  • 添加了对通过启用配置文件(pyjion.enable_profiling())来配置文件编译函数的支持。
  • 添加了对配置文件C函数调用、返回和异常的支持。
  • 实现了5-10个参数的函数和方法的更快的调用路径。
  • 修复了.NET EE中页面大小默认为0的bug,这导致断言失败(并且无法编译函数),将修复大量之前无法编译的函数

0.1.0

  • 添加了对调试编译后的函数和模块的支持,通过启用跟踪(pyjion.enable_tracing()
  • 添加了在跟踪启用时,在运行时捕获未处理/已处理异常的支持
  • 添加了对指令级跟踪的支持
  • 修复了在执行Pyjion时与pydevd(VScode/PyCharm调试器)配合使用会导致Python进程崩溃的bug(#7),原因是双重释放代码对象

0.0.7

  • 添加了WSGI中间件函数,以启用Flask和Django的Pyjion(#67)
  • 修复了映射类型字典合并时错误地引发类型错误的bug(#66)

0.0.6

  • 实现了将“大型”方法反汇编为CIL的支持(#27)
  • 为pyjion C扩展添加了类型存根
  • 修复了合并或更新派生字典时由于类型错误而失败的bug(#28)

0.0.5

  • 修复了一个关键bug,其中大量参数的方法调用,参数为元组,在GC收集时可能造成段错误
  • 测试了对IPython REPL的支持
  • 修复了在启用JIT后导入pyjion.dis会导致栈溢出的bug
  • 大约有50%的几率正常工作,不会导致您的计算机爆炸,或者更糟,段错误

0.0.4

  • 为Linux添加了堆栈探针辅助工具(将在更多场景中使用JIT)
  • 启用了在Linux上运行单元测试的支持
  • 修复了JIT在方法调用失败(由于不良查找)时崩溃的bug
  • 为Linux实现了辅助方法重定向,以支持PIC编译符号
  • 大约有35%的几率正常工作,不会导致您的计算机爆炸,或者更糟,段错误
  • 改进了Linux上.NET库的发现
  • 修复了生成杂乱命名的日志文件(应为JIT定时日志)的bug

0.0.3

  • 适用于Ubuntu、Debian、macOS 10.15、11(10.16)和Windows x64的bdist_wheel可安装
  • 包含clrjit.so捆绑的许多linux2014 wheel可安装
  • 添加了对多线程/多进程的支持
  • 修复了当系统上有两个Python 3.9发行版时,wheel会损坏的bug
  • 大约有30%的几率正常工作,不会导致您的计算机爆炸,或者更糟,段错误。

0.0.2

  • 适用于macOS、Windows和(几乎)Linux的源代码分发支持。

0.0.1

  • 在我的机器上编译成功

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分布

pyjion-2.0.0.tar.gz (166.3 kB 查看散列)

上传时间

构建分布

pyjion-2.0.0-cp310-cp310-win_arm64.whl (372.2 kB 查看散列)

上传时间 CPython 3.10 Windows ARM64

pyjion-2.0.0-cp310-cp310-win_amd64.whl (372.2 kB 查看散列)

上传时间 CPython 3.10 Windows x86-64

pyjion-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.0 MB 查看散列)

上传时间 CPython 3.10 manylinux: glibc 2.17+ x86-64

pyjion-2.0.0-cp310-cp310-macosx_11_0_x86_64.whl (411.0 kB 查看散列)

上传时间 CPython 3.10 macOS 11.0+ x86-64

pyjion-2.0.0-cp310-cp310-macosx_11_0_universal2.whl (599.0 kB 查看散列)

上传时间 CPython 3.10 macOS 11.0+ universal2 (ARM64, x86-64)

由以下支持