0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是常量折叠?Python如何优雅地实现它

科技绿洲 来源:Python实用宝典 作者:Python实用宝典 2023-10-30 11:10 次阅读

每种编程语言为了表现出色,并且实现卓越的性能,都需要大量编译器级的优化。

一种著名的优化技术是“常量折叠”(Constant Folding):在编译期间,编译器会设法识别出常量表达式,对其进行求值,然后用求值的结果来替换表达式,从而使得运行时更精简。

在本文中,我们深入探讨了什么是常量折叠,了解了它在 Python 世界中的适用范围,最后解读了 Python 的源代码(即 CPython),并分析出 Python 是如何优雅地实现它。

常量折叠

所谓常量折叠,指的是在编译时就查找并计算常量表达式,而不是在运行时再对其进行计算,从而会使运行时更加精简和快速。

>> > day_sec = 24 * 60 * 60

当编译器遇到一个常量表达式时,如上所述,它将对表达式求值,并作替换。

通常而言,表达式会被“抽象语法树”( Abstract Syntax Tree,简写为 AST)中的计算值所替换,但是这完全取决于语言的实现。

因此,上述表达式可以等效地被执行为:

>> > day_sec = 86400

Python 中的常量折叠

在 Python 中,我们可以使用汇编模块(Disassembler)获取 CPython 字节码,从而更好地了解代码执行的过程。

当使用dis模块反汇编上述常量表达式时,我们会得到以下字节码:

>> > import dis
 >> > dis.dis("day_sec = 24 * 60 * 60")

        0 LOAD_CONST               0 (86400)
        2 STORE_NAME               0 (day_sec)
        4 LOAD_CONST               1 (None)
        6 RETURN_VALUE

从字节码中可以看出,它只有一个LOAD_CONST ,以及一个已经计算好的值86400

这表明 CPython 解释器在解析和构建抽象语法树期间,会折叠常量表达式 24 * 60 * 60,并将其替换为计算值 86400。

常量折叠的适应范围

Python 会尝试折叠每一个常量表达式,但在某些情况下,即使该表达式是常量,但是 Python 并不会对其进行折叠。

例如,Python 不会折叠x = 4 ** 64,但会折叠 x = 2 ** 64

图片

除了算术表达式,Python 还会折叠涉及字符串和元组的表达式,其中,长度不超过 4096 的字符串常量表达式会被折叠。

>> > a = "-" * 4096   # folded
 >> > a = "-" * 4097   # not folded
 >> > a = "--" * 4096  # not folded

常量折叠的内部细节

现在,我们将重点转移到内部的实现细节,即关注 CPython 在哪里以及如何实现常量折叠。

所有的 AST 优化(包括常量折叠)都可以在 ast_opt.c 文件中找到。基本的开始函数是 astfold_expr,它会折叠 Python 源码中包含的所有表达式。

这个函数以递归方式遍历 AST,并试着折叠每个常量表达式,如下面的代码片段所示:

图片

astfold_expr 在折叠某个表达式之前,会尝试折叠其子表达式(操作对象),然后将折叠操作代理给特定的表达式折叠函数。

特定操作的折叠函数对表达式求值,并返回计算后的常数,然后将其放入 AST 中。

例如,每当 astfold_expr 遇到二值运算时,它便调用 fold_binop,递归地计算两个子操作对象(表达式) 。

fold_binop 函数返回计算后的常量值,如下面的代码片段所示:

图片

fold_binop 函数通过检查当前运算符的种类,然后调用其相应的处理函数来折叠二值运算。例如,如果当前的操作是加法运算,为了计算最终值,它会对其左侧和右侧操作数调用 PyNumber_Add。

怎样优雅?

为了有效地折叠某些模式或类型的常量表达式,CPython 不会写特殊的逻辑,而是调用相同的通用代码。例如,在折叠时,它会调用通用的 PyNumber_Add 函数,跟执行常规的加法操作一样。

因此,CPython 通过确保其通用代码/计算过程可以处理常量表达式的求值,从而消除了编写特殊函数来处理常量折叠的需要。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2671

    浏览量

    47340
  • 字符串
    +关注

    关注

    1

    文章

    577

    浏览量

    20485
  • 编译器
    +关注

    关注

    1

    文章

    1618

    浏览量

    49051
  • python
    +关注

    关注

    56

    文章

    4782

    浏览量

    84453
收藏 人收藏

    评论

    相关推荐

    折叠匹配滤波器的实现

    折叠匹配率波器的实现过程
    发表于 10-16 16:47

    【AI学习】第4篇--Python编辑入门

    Python是一种流行的计算机程序语言,在当今的AI科技潮流下,显得更抢眼,因为在AI科学领域的许多链接库、以及相关的框架(Framework)或平台(Platform)都是Python作为
    发表于 11-03 10:18

    2.1 python常量与变量

    2.1 python常量与变量变量:在程序运行过程中,值会发生变化的量常量:在程序运行过程中,值不会发生变化的量无论是变量还是常量,在创建时都会在内存中开辟一块空间,用于保存
    发表于 02-16 18:34

    Python常量与变量基础知识详解

    Python是一门强类型的动态语言。 字面常量,变量没有类型,变量只是在特定的时间指向特定的对象而已,变量所指向的对象是有类型的。 变量:变量在赋值时被创建,它可以是任何对象的引用,但必须在引用前被
    发表于 12-14 05:31 1809次阅读

    让你的 Python 代码优雅又地道

    Python社区文化的浇灌下,演化出了一种独特的代码风格,去指导如何正确地使用Python,这就是常说的pythonic。一般说地道(idiomatic)的python代码,就是指这份代码很
    的头像 发表于 03-06 10:35 3594次阅读

    python基础教程之python入门教程中文手册免费下载

    Python是一种容易学习的强大语言。包括了高效的高级数据结构,提供了一个简单但很有效的方式进行面向对象编程。Python 优雅的语法,动态类型,以及
    发表于 08-29 08:00 31次下载

    Python入门之Python基础教程资料免费下载

    Python 是种易学而强大的编程语言 。 包含了高效的高级数据结构 , 能够用简单而高效的方式进行面向对象编程 。 Python 优雅的语法和动态类型, 以及
    发表于 10-16 08:00 39次下载

    Python学习手册免费下载

    Python 是一种容易学习的强大语言。包括了高效的高级数据结构,提供了一个简单但很有有效的方式以便进行面向对象编程。Python 优雅的语法,动态数据类型,以及
    发表于 03-01 16:12 9次下载
    <b class='flag-5'>Python</b>学习手册免费下载

    Python学习手册免费下载

    Python 是一种容易学习的强大语言。包括了高效的高级数据结构,提供了一个简单但很有有效的方式以便进行面向对象编程。Python 优雅的语法,动态数据类型,以及
    发表于 03-01 16:12 26次下载
    <b class='flag-5'>Python</b>学习手册免费下载

    Python优雅的日志记录解决方案Loguru

      Loguru: 更优雅的日志记录解决方案! loguru  是一个  Python  简易且强大的第三方日志记录库,该库旨在通过添加一系列有用的功能来解决标准记录器的注意事项,从而减少
    的头像 发表于 11-18 11:24 2950次阅读

    深入了解python常量与变量

      Python 的变量和常量不需要事先声明类型,这是根据Python的动态语言特性而来。
    的头像 发表于 02-16 18:22 1892次阅读
    深入了解<b class='flag-5'>python</b><b class='flag-5'>常量</b>与变量

    Python实现所有算法-基本牛顿法

    Python实现所有算法-二分法 Python实现所有算法-力系统是否静态平衡 Python实现
    的头像 发表于 07-13 10:40 1614次阅读

    浅谈指针常量常量指针

    这节课我们来讲一讲指针常量常量指针。
    的头像 发表于 02-21 09:27 1036次阅读

    Python优雅之处:Descriptor(描述符)

    语法糖的实现上也有使用到(在下面的文章会一一介绍)。 当你点进这篇文章时 你也许没学过描述符,甚至没听过描述符。 或者你对描述符只是一知半解 无论你是哪种,本篇都将带你全面的学习描述符,一起来感受 Python 语言的优雅。 1
    的头像 发表于 11-02 10:52 967次阅读
    <b class='flag-5'>Python</b>的<b class='flag-5'>优雅</b>之处:Descriptor(描述符)

    python语言特点有哪些

    Python是一种高级编程语言,由Guido van Rossum于1991年首次发布。具有许多独特的特点,这些特点使得Python在软件开发领域变得非常流行。以下是关于Python
    的头像 发表于 11-29 14:29 1046次阅读