0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是常量折疊?Python如何優(yōu)雅地實現(xiàn)它

科技綠洲 ? 來源:Python實用寶典 ? 作者:Python實用寶典 ? 2023-10-30 11:10 ? 次閱讀

每種編程語言為了表現(xiàn)出色,并且實現(xiàn)卓越的性能,都需要大量編譯器級的優(yōu)化。

一種著名的優(yōu)化技術(shù)是“常量折疊”(Constant Folding):在編譯期間,編譯器會設(shè)法識別出常量表達式,對其進行求值,然后用求值的結(jié)果來替換表達式,從而使得運行時更精簡。

在本文中,我們深入探討了什么是常量折疊,了解了它在 Python 世界中的適用范圍,最后解讀了 Python 的源代碼(即 CPython),并分析出 Python 是如何優(yōu)雅地實現(xiàn)它。

常量折疊

所謂常量折疊,指的是在編譯時就查找并計算常量表達式,而不是在運行時再對其進行計算,從而會使運行時更加精簡和快速。

>> > day_sec = 24 * 60 * 60

當(dāng)編譯器遇到一個常量表達式時,如上所述,它將對表達式求值,并作替換。

通常而言,表達式會被“抽象語法樹”( Abstract Syntax Tree,簡寫為 AST)中的計算值所替換,但是這完全取決于語言的實現(xiàn)。

因此,上述表達式可以等效地被執(zhí)行為:

>> > day_sec = 86400

Python 中的常量折疊

在 Python 中,我們可以使用匯編模塊(Disassembler)獲取 CPython 字節(jié)碼,從而更好地了解代碼執(zhí)行的過程。

當(dāng)使用dis模塊反匯編上述常量表達式時,我們會得到以下字節(jié)碼:

>> > 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

從字節(jié)碼中可以看出,它只有一個LOAD_CONST ,以及一個已經(jīng)計算好的值86400。

這表明 CPython 解釋器在解析和構(gòu)建抽象語法樹期間,會折疊常量表達式 24 * 60 * 60,并將其替換為計算值 86400。

常量折疊的適應(yīng)范圍

Python 會嘗試折疊每一個常量表達式,但在某些情況下,即使該表達式是常量,但是 Python 并不會對其進行折疊。

例如,Python 不會折疊x = 4 ** 64,但會折疊 x = 2 ** 64

圖片

除了算術(shù)表達式,Python 還會折疊涉及字符串和元組的表達式,其中,長度不超過 4096 的字符串常量表達式會被折疊。

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

常量折疊的內(nèi)部細節(jié)

現(xiàn)在,我們將重點轉(zhuǎn)移到內(nèi)部的實現(xiàn)細節(jié),即關(guān)注 CPython 在哪里以及如何實現(xiàn)常量折疊。

所有的 AST 優(yōu)化(包括常量折疊)都可以在 ast_opt.c 文件中找到?;镜拈_始函數(shù)是 astfold_expr,它會折疊 Python 源碼中包含的所有表達式。

這個函數(shù)以遞歸方式遍歷 AST,并試著折疊每個常量表達式,如下面的代碼片段所示:

圖片

astfold_expr 在折疊某個表達式之前,會嘗試折疊其子表達式(操作對象),然后將折疊操作代理給特定的表達式折疊函數(shù)。

特定操作的折疊函數(shù)對表達式求值,并返回計算后的常數(shù),然后將其放入 AST 中。

例如,每當(dāng) astfold_expr 遇到二值運算時,它便調(diào)用 fold_binop,遞歸地計算兩個子操作對象(表達式) 。

fold_binop 函數(shù)返回計算后的常量值,如下面的代碼片段所示:

圖片

fold_binop 函數(shù)通過檢查當(dāng)前運算符的種類,然后調(diào)用其相應(yīng)的處理函數(shù)來折疊二值運算。例如,如果當(dāng)前的操作是加法運算,為了計算最終值,它會對其左側(cè)和右側(cè)操作數(shù)調(diào)用 PyNumber_Add。

怎樣優(yōu)雅?

為了有效地折疊某些模式或類型的常量表達式,CPython 不會寫特殊的邏輯,而是調(diào)用相同的通用代碼。例如,在折疊時,它會調(diào)用通用的 PyNumber_Add 函數(shù),跟執(zhí)行常規(guī)的加法操作一樣。

因此,CPython 通過確保其通用代碼/計算過程可以處理常量表達式的求值,從而消除了編寫特殊函數(shù)來處理常量折疊的需要。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 模塊
    +關(guān)注

    關(guān)注

    7

    文章

    2717

    瀏覽量

    47544
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    579

    瀏覽量

    20549
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1635

    瀏覽量

    49166
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4797

    瀏覽量

    84787
收藏 人收藏

    評論

    相關(guān)推薦

    折疊匹配濾波器的實現(xiàn)

    折疊匹配率波器的實現(xiàn)過程
    發(fā)表于 10-16 16:47

    【AI學(xué)習(xí)】第4篇--Python編輯入門

    Python是一種流行的計算機程序語言,在當(dāng)今的AI科技潮流下,顯得更搶眼,因為在AI科學(xué)領(lǐng)域的許多鏈接庫、以及相關(guān)的框架(Framework)或平臺(Platform)都是Python作為
    發(fā)表于 11-03 10:18

    2.1 python常量與變量

    2.1 python常量與變量變量:在程序運行過程中,值會發(fā)生變化的量常量:在程序運行過程中,值不會發(fā)生變化的量無論是變量還是常量,在創(chuàng)建時都會在內(nèi)存中開辟一塊空間,用于保存
    發(fā)表于 02-16 18:34

    Python常量與變量基礎(chǔ)知識詳解

    Python是一門強類型的動態(tài)語言。 字面常量,變量沒有類型,變量只是在特定的時間指向特定的對象而已,變量所指向的對象是有類型的。 變量:變量在賦值時被創(chuàng)建,它可以是任何對象的引用,但必須在引用前被
    發(fā)表于 12-14 05:31 ?1816次閱讀

    讓你的 Python 代碼優(yōu)雅又地道

    Python社區(qū)文化的澆灌下,演化出了一種獨特的代碼風(fēng)格,去指導(dǎo)如何正確地使用Python,這就是常說的pythonic。一般說地道(idiomatic)的python代碼,就是指這份代碼很
    的頭像 發(fā)表于 03-06 10:35 ?3638次閱讀

    python基礎(chǔ)教程之python入門教程中文手冊免費下載

    Python是一種容易學(xué)習(xí)的強大語言。包括了高效的高級數(shù)據(jù)結(jié)構(gòu),提供了一個簡單但很有效的方式進行面向?qū)ο缶幊獭?b class='flag-5'>Python 優(yōu)雅的語法,動態(tài)類型,以及
    發(fā)表于 08-29 08:00 ?31次下載

    Python入門之Python基礎(chǔ)教程資料免費下載

    Python 是種易學(xué)而強大的編程語言 。 包含了高效的高級數(shù)據(jù)結(jié)構(gòu) , 能夠用簡單而高效的方式進行面向?qū)ο缶幊?。 Python 優(yōu)雅的語法和動態(tài)類型, 以及
    發(fā)表于 10-16 08:00 ?39次下載

    Python學(xué)習(xí)手冊免費下載

    Python 是一種容易學(xué)習(xí)的強大語言。包括了高效的高級數(shù)據(jù)結(jié)構(gòu),提供了一個簡單但很有有效的方式以便進行面向?qū)ο缶幊獭?b class='flag-5'>Python 優(yōu)雅的語法,動態(tài)數(shù)據(jù)類型,以及
    發(fā)表于 03-01 16:12 ?9次下載
    <b class='flag-5'>Python</b>學(xué)習(xí)手冊免費下載

    Python學(xué)習(xí)手冊免費下載

    Python 是一種容易學(xué)習(xí)的強大語言。包括了高效的高級數(shù)據(jù)結(jié)構(gòu),提供了一個簡單但很有有效的方式以便進行面向?qū)ο缶幊獭?b class='flag-5'>Python 優(yōu)雅的語法,動態(tài)數(shù)據(jù)類型,以及
    發(fā)表于 03-01 16:12 ?26次下載
    <b class='flag-5'>Python</b>學(xué)習(xí)手冊免費下載

    Python優(yōu)雅的日志記錄解決方案Loguru

    ? Loguru: 更優(yōu)雅的日志記錄解決方案! loguru ?是一個? Python ?簡易且強大的第三方日志記錄庫,該庫旨在通過添加一系列有用的功能來解決標準記錄器的注意事項,從而減少
    的頭像 發(fā)表于 11-18 11:24 ?3006次閱讀

    深入了解python常量與變量

      Python 的變量和常量不需要事先聲明類型,這是根據(jù)Python的動態(tài)語言特性而來。
    的頭像 發(fā)表于 02-16 18:22 ?1931次閱讀
    深入了解<b class='flag-5'>python</b><b class='flag-5'>常量</b>與變量

    Python實現(xiàn)所有算法-基本牛頓法

    Python實現(xiàn)所有算法-二分法 Python實現(xiàn)所有算法-力系統(tǒng)是否靜態(tài)平衡 Python實現(xiàn)
    的頭像 發(fā)表于 07-13 10:40 ?1655次閱讀

    淺談指針常量常量指針

    這節(jié)課我們來講一講指針常量常量指針。
    的頭像 發(fā)表于 02-21 09:27 ?1086次閱讀

    Python優(yōu)雅之處:Descriptor(描述符)

    語法糖的實現(xiàn)上也有使用到(在下面的文章會一一介紹)。 當(dāng)你點進這篇文章時 你也許沒學(xué)過描述符,甚至沒聽過描述符。 或者你對描述符只是一知半解 無論你是哪種,本篇都將帶你全面的學(xué)習(xí)描述符,一起來感受 Python 語言的優(yōu)雅。 1
    的頭像 發(fā)表于 11-02 10:52 ?1024次閱讀
    <b class='flag-5'>Python</b>的<b class='flag-5'>優(yōu)雅</b>之處:Descriptor(描述符)

    python語言特點有哪些

    Python是一種高級編程語言,由Guido van Rossum于1991年首次發(fā)布。具有許多獨特的特點,這些特點使得Python在軟件開發(fā)領(lǐng)域變得非常流行。以下是關(guān)于Python
    的頭像 發(fā)表于 11-29 14:29 ?1187次閱讀