中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Cpython3.9源碼分析python中的大小整數

發布時間:2023-04-21 17:04:22 來源:億速云 閱讀:117 作者:iii 欄目:開發技術

這篇“Cpython3.9源碼分析python中的大小整數”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Cpython3.9源碼分析python中的大小整數”文章吧。

小整數

/* interpreter state */

#define _PY_NSMALLPOSINTS           257
#define _PY_NSMALLNEGINTS           5

這是CPython中定義的兩個常量,它們用于控制解釋器狀態中的小整數對象池。在CPython中,小整數對象池是一種優化機制,用于減少對常用小整數的內存分配和銷毀開銷。

_PY_NSMALLPOSINTS定義了正小整數對象池的大小。在這里,其值設置為257,表示解釋器將為從0到256(包含0和256)的整數預分配對象并緩存。這些整數在很多場景下會被頻繁使用,所以事先創建并緩存它們可以提高性能。

_PY_NSMALLNEGINTS定義了負小整數對象池的大小。在這里,其值設置為5,表示解釋器將為從-1到-5(包含-1和-5)的整數預分配對象并緩存。

在Python解釋器啟動時,這些小整數對象會被創建并放入對象池。當需要這些整數值時,解釋器會直接從對象池中獲取對應的對象,而不是動態創建新對象。這樣,對于這些小整數值的操作可以更快地進行,節省了內存分配和銷毀的開銷。

static PyObject *
get_small_int(sdigit ival)
{
    assert(IS_SMALL_INT(ival));
    PyThreadState *tstate = _PyThreadState_GET();
    PyObject *v = (PyObject*)tstate->interp->small_ints[ival + NSMALLNEGINTS];
    Py_INCREF(v);
    return v;
}

typedef int32_t sdigit; /* signed variant of digit */

#define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS)

這是get_small_int函數的實現,它用于從小整數對象池中獲取一個指定值的小整數對象。小整數對象池包含了一定范圍內的整數對象,主要是為了避免對這些常用的整數對象進行頻繁的內存分配和銷毀。

get_small_int函數接受一個sdigit類型的參數ival,表示要獲取的整數值。在函數內部,首先使用assert(IS_SMALL_INT(ival))確保傳入的整數值ival在小整數對象池的范圍內。

接下來,函數獲取當前線程狀態(PyThreadState)并從其中獲取解釋器狀態(tstate->interp)。解釋器狀態包含了小整數對象池,即small_ints數組

然后,根據ival計算出在small_ints數組中的索引(ival + NSMALLNEGINTS),并將對應位置的對象賦值給vNSMALLNEGINTS是一個宏定義,表示負小整數的個數。假設我們有一個整數值 ival,我們想要在 small_ints 數組中查找這個值對應的預分配的小整數對象。NSMALLNEGINTS 是預分配的負數的數量。在 CPython 中,NSMALLNEGINTS 的值通常為5,表示有5個預分配的負整數對象(-1, -2, -3, -4, -5)。

現在,我們將通過計算 ival + NSMALLNEGINTS 來找到 small_ints 數組中的索引。例如,假設 ival 為3。那么,我們可以計算索引如下:

index = ival + NSMALLNEGINTS
index = 3 + 5
index = 8

這意味著 small_ints 數組中的第8個元素(從0開始計數)是我們要查找的整數對象。在這個例子中,我們將找到預分配的小整數對象3,并將其引用計數加1,然后返回這個對象。

接下來,通過調用Py_INCREF(v)增加v的引用計數,以防止對象在其引用計數變為0時被錯誤地回收。

最后,返回指向小整數對象的指針v

總之,get_small_int函數的作用是從小整數對象池中獲取一個指定值的小整數對象,并增加其引用計數,然后返回該對象。這樣可以提高對常用小整數的操作性能。

大整數

/* Long integer representation.
   The absolute value of a number is equal to
        SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
   Negative numbers are represented with ob_size < 0;
   zero is represented by ob_size == 0.
   In a normalized number, ob_digit[abs(ob_size)-1] (the most significant
   digit) is never zero.  Also, in all cases, for all valid i,
        0 <= ob_digit[i] <= MASK.
   The allocation function takes care of allocating extra memory
   so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available.

   CAUTION:  Generic code manipulating subtypes of PyVarObject has to
   aware that ints abuse  ob_size's sign bit.
*/

這是CPython源碼中關于長整數表示的一段注釋。它解釋了PyLongObject如何表示大整數的絕對值和符號。讓我們逐行分析這個注釋:

1.首先,注釋指出大整數的絕對值等于:

SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)

ob_digit表示長整數的每個“數字”,SHIFT是每個“數字”的位數,通常為30或15。ob_size表示長整數的符號和長度,它的絕對值表示長整數的長度,即“數字”的個數。

2.對于負數,ob_size小于0。對于0,ob_size等于0。

3.在規范化的數中,最高有效位(即最高“數字”)永遠不會為零。此外,在所有情況下,對于所有有效的i,ob_digit[i]的取值范圍在0到MASK之間。MASK的值通常為(1 << PyLong_SHIFT) - 1,即2**PyLong_SHIFT - 1

4.注釋還提到分配函數負責分配額外的內存,以確保ob_digit[0]ob_digit[abs(ob_size)-1]實際上是可用的。

5.最后,注釋中的“警告”部分提醒開發者,操縱PyVarObject子類型的通用代碼需要注意整數會濫用ob_size的符號位。這是因為ob_size的符號位同時表示整數的長度和符號,而通常情況下ob_size僅用于表示長度。

額外解釋

ob_digit 是一個表示大整數中每個 “數字” 的數組,它是一個整數數組,用于表示長整數對象(PyLongObject)中的整數值。每個 “數字” 都有一個固定的位數,由 PyLong_SHIFT 定義(通常為 30 或 15)。例如,假設我們有一個長整數對象,其值為 12345678901234567890。

在這個例子中,假設 PyLong_SHIFT 為 30,這意味著每個 “數字” 可以表示 2^30 = 1073741824 個不同的值。為了將這個大整數表示為 ob_digit 數組,我們需要將整數拆分為基于 2^30 的 “數字”。在這種情況下,我們可以將整數表示為:

12345678901234567890 = 4 * 2^(30*2) + 726238597 * 2^(30*1) + 1026062870 * 2^(30*0)

所以,ob_digit 數組將包含以下元素:

ob_digit[0] = 1026062870
ob_digit[1] = 726238597
ob_digit[2] = 4

在實際的 CPython 源碼中,PyLongObject 的定義如下:

typedef struct {
    PyObject_VAR_HEAD
    digit ob_digit[1];
} PyLongObject;

在這里,ob_digit 是一個長度為1的數組,但實際上,它是一個可變長度數組,根據所需的 “數字” 數量動態分配。要注意的是,當一個 PyLongObject 被創建時,會根據整數值的大小動態分配適當數量的空間來存儲 ob_digit 數組。

以上就是關于“Cpython3.9源碼分析python中的大小整數”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

邵武市| 平阴县| 灵武市| 石棉县| 东丽区| 康保县| 托里县| 嘉峪关市| 和田市| 弥勒县| 马龙县| 靖安县| 潍坊市| 三都| 南乐县| 宁安市| 高淳县| 会泽县| 镇宁| 德州市| 新津县| 基隆市| 靖宇县| 富源县| 西乡县| 彭泽县| 富民县| 崇州市| 靖边县| 丹巴县| 湖南省| 眉山市| 安仁县| 扶绥县| 江油市| 广水市| 界首市| 连云港市| 阜城县| 定结县| 宁化县|