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

    文章

    2484

    浏览量

    46530
  • 字符串
    +关注

    关注

    1

    文章

    551

    浏览量

    20126
  • 编译器
    +关注

    关注

    1

    文章

    1577

    浏览量

    48617
  • python
    +关注

    关注

    51

    文章

    4675

    浏览量

    83467
收藏 人收藏

    评论

    相关推荐

    如何让你的Python代码竟优雅又地道

    pythonic的代码简练,明确,优雅,绝大部分时候执行效率高。阅读pythonic的代码能体会到“代码是写给人看的,只是顺便让机器能运行”畅快。这篇文章是网友Jeff Paine整理的他在2013年...
    的头像 发表于 02-03 12:35 4405次阅读

    3个关键字让你的Python代码更优雅

    尽管 Python 不是为函数式编程而构建的,但它确实支持函数式编程的一些非常棒的特性。如果您希望您的程序更优雅、更可靠和无状态,那么函数式编程可能是您的考虑因素。
    发表于 11-02 09:52 334次阅读

    折叠匹配滤波器的实现

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

    重卡后视镜自动折叠怎么实现

    各位电子发烧大佬好,我想请问一下,重卡电动后视镜可用什么电动机来进行操作运转,实现自动折叠功能呢?
    发表于 01-07 22:39

    汇编代码折叠

    MPASM中创建自定义代码折叠:不支持...”)基于C的项目的代码折叠工作得很好,其中一些代码折叠工作得很好我的大型ASM项目也可以使用这个特性。IDE可能已经实现了,但是我错过了吗?
    发表于 04-14 09:21

    【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 1679次阅读

    让你的 Python 代码优雅又地道

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

    深入了解python常量与变量

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

    浅谈指针常量常量指针

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

    C语言的常量-2

    在C语言中,字符型常量是最特别的一种常量。他的特别之处在于我们需要对其使用指定的定界符对其进行限制。定界符为 ‘’ 。字符型常量可以分为两种,一种是字符常量,另一种是字符串
    的头像 发表于 02-21 15:02 418次阅读
    C语言的<b class='flag-5'>常量</b>-2

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

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

    python语言特点有哪些

    、详实和细致的描述,共计超过1500字。 简洁优雅Python以简洁和优雅的语法而著称。相对于其他编程语言,Python代码通常看起来更加清晰易读。这得益于
    的头像 发表于 11-29 14:29 457次阅读

    优雅停机是什么?SpringBoot+Nacos+k8s实现优雅停机

    优雅停机是什么?网上说的优雅下线、无损下线,都是一个意思。
    的头像 发表于 02-20 10:00 502次阅读
    <b class='flag-5'>优雅</b>停机是什么?SpringBoot+Nacos+k8s<b class='flag-5'>实现</b><b class='flag-5'>优雅</b>停机