1. 程式人生 > >Python的len函式探究

Python的len函式探究

有問題或者指導歡迎致信[email protected]來交流。

問題

平時經常使用到len函式來求一個List或者其他的長度,但是沒怎麼思考過,len函式的時間開銷是多少。 雖然感覺上不會用從頭到尾數一遍這種很弱的方法,而是會儲存一個size變數,但是一切還是要用事實來說話

程式設計驗證

首先很簡單粗暴地使用程式設計來看看時間花銷,分別驗證不同長度的List,呼叫len函式的時間開銷
A = [0 for i in range(1000)]
    B = [0 for i in range(100000)]
    C = [0 for i in range(10000000)]

    import time
    start = time.time()
    length = len(A)
    end = time.time()
    print length, 'time cost', end-start

    start = time.time()
    length = len(B)
    end = time.time()
    print length, 'time cost', end-start

    start = time.time()
    length = len(C)
    end = time.time()
    print length, 'time cost', end-start

結果如下:
1000 time cost 9.53674316406e-07
100000 time cost 9.53674316406e-07
10000000 time cost 0.0

可以看出的確符合我們的期望,在長度相差很大的情況下時間開銷相似,第三種情況下長度最長卻時間短到測不出來

原始碼分析

在Python目錄下的include資料夾中找到了如下的檔案listobject.h,其中看到一段程式碼
PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size);
PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *);
PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t);
PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *);
PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *);
PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *);

看出PyList_Size對應的就是len函式。而在object.h中看到一段程式碼
/* PyObject_VAR_HEAD defines the initial segment of all variable-size
 * container objects.  These end with a declaration of an array with 1
 * element, but enough space is malloc'ed so that the array actually
 * has room for ob_size elements.  Note that ob_size is an element count,
 * not necessarily a byte count.
 */
#define PyObject_VAR_HEAD               \
    PyObject_HEAD                       \
    Py_ssize_t ob_size; /* Number of items in variable part */

所以的確是儲存了一個變數記錄size,當我們呼叫len函式時候直接找到這個size就行了,所以無論多長的List,呼叫len函式花費的時間基本相同,可以認為len函式時間開銷為O(1)

相關推薦

c++公有虛擬函式與非公有虛擬函式探究

(一)公有虛擬函式   子類通過覆蓋公有虛擬函式的方式實現多型是最常見的情況。指向子類物件的基類指標呼叫被子類覆蓋的函式,實際上,呼叫的是子類的函式。以下程式碼:   class Base { public:     virtual void foo()     {    

Python的len函式探究

有問題或者指導歡迎致信[email protected]來交流。 問題 平時經常使用到len函式來求一個List或者其他的長度,但是沒怎麼思考過,len函式的時間開銷是多少。 雖然感覺上不會

gcc之inline函式探究

1、引子:行內函數(以下稱為inline函式)的行為類似於巨集,但是會像函式一樣進行引數的靜態型別檢查。因此gcc中很多地方傾向於使用inline函式來替代巨集。但是inline函式在gcc中應該如何使用呢?函式被內聯之後究竟有哪些改變呢? #include "stdio.

用C語言探究函式遞迴的巧妙之處(以斐波那契數列為例)

對於許多C語言的初學者來說,函式是一個比較重要的版塊.函式的使用不僅在學習程式設計的時期可以方便我們解決一些問題.它在未來的工作中也是程式設計師們經常運用的東西.而函式的遞迴是函式這一版塊比較難懂的東西.因此小編以輸出斐波那契數列的第N項為例,來探討函式的遞迴的應用給我們的程式碼帶來的方便.

libc system函式探究

system導致父程序等待 在mac上的線上幫助有對system的如下說明: The system() function hands the argument command to the command interpreter sh(1). The calling p

JavaScript中Promise函式then的奧祕探究

Promise概述 Promise物件是CommonJS工作組提出的一種規範,目的是為非同步操作提供統一介面。 那麼,什麼是Promises? 首先,它是一個物件,也就是說與其他JavaScript物件的用法,沒有什麼兩樣;其次,它起到代理作用(proxy),充當非

探究JS中Promise函式then的奧祕

Promise概述 Promise物件是CommonJS工作組提出的一種規範,目的是為非同步操作提供統一介面。 那麼,什麼是Promises? 首先,它是一個物件,也就是說與其他JavaScript物件的用法,沒有什麼兩樣;其次,它起到代理作用(proxy),充當非同步操作與回撥

關於umount2函式的MNT_DETACH引數的探究

在manpages中有這麼一段介紹: MNT_DETACH (since Linux 2.4.11) Perform a lazy unmount: make the mount point unavailable for new

Lua 函式用法探究

 在 中有涉及到函式的用法,但只是普通的應用,並沒有深成次的研究一下,介於函式用的還是比較多的就專門做個專題研究一下~   一、函式、變數的用法              函式的定義用關鍵字function 。然後加函式名和變數。注意後面沒有do。最後以end結束。

printf函式引數的執行順序的簡單探究

大部分人應該都對printf函式比較瞭解,這也是作為c語言初學者第一個遇到的函式吧!! 哈哈,就是那個什麼(列印hello,world)啊,當時當被問到printf函式的執行順序的時候,好多人

深入探究connect函式

 connect,是QT中的連線函式,將訊號傳送者sender物件中的訊號signal與接受者receiver中的member槽函式聯絡起來。  QObject::connect的定義是這樣的:     static bool connect(const QObject

tensorflow: 損失函式(Losses Functions) 探究

損失函式定義 Losses The loss ops measure error between two tensors, or between a tensor and zero

cublasGemmEx函式應用-探究8bit矩陣乘

介紹 cublasGemmEx 是CUDA8.0中cuBLAS新出的函式,是cublasgemm()類函式的擴充套件,也是目前來看功能最強大的矩陣乘函數了。該函式另一強大之處在於支援多種計算模式(compute type),其中就包括CUDA 8.0新出的FP

《coredump問題原理探究》Linux x86版3.2節棧佈局之函式

看一個例子: void FuncA() { } void FuncB() { FuncA(); } int main() { FuncB(); return 0; } 用下面命令編譯出它釋出版本: [[email protecte

探究C++中的成員函式指標和虛擬函式

say something 相信對C++物件有一定了解的話,應該都會知道,在C++中物件的實現中,成員函式和成員變數是分離的 所以我們所談到的非靜態成員函式其實只是一個普通的函式(不過被編譯器所隱藏,必須繫結到特定的物件上才能執行) 靜態成員函式實際上就真

函式呼叫過程探究

面試時經常遇到一些蛋疼的題目,儘管實際中從來沒用到,或者大家工作過程中沒有仔細思考的,今天來轉帖一下這個函式呼叫過程,以及引數是怎麼壓棧出棧的: 文章來自:http://www.cnblogs.com/bangerlee/archive/2012/05/22/2508772

Golang原始碼學習:使用gdb除錯探究Golang函式呼叫棧結構

本文所使用的golang為1.14,gdb為8.1。 一直以來對於函式呼叫都僅限於函式呼叫棧這個概念上,但對於其中的詳細結構卻瞭解不多。所以用gdb除錯一個簡單的例子,一探究竟。 ## 函式呼叫棧的結構(以下簡稱棧) 棧包含以下作用: - 儲存函式返回地址。 - 儲存呼叫者的rbp。 - 儲存區域性變數。

char * 與char []探究理解

nbsp eof 文章 野指針 print 參數 函數 tar 自動 問題引入 以前一直認為二者是一樣的,今天突然發現他們還是有很大的不同的。例如char *a = "abc"和char b[] = "abc",當我使用strcat(b,a)時得到的b是二者的結合,當我使

java深入探究06

定義 auth ttr null hist context 編號 http 使用 Tomcat中獲取資源文件: ServletContext().getRealPath(/WEB-INF/classes/db.properties);//獲取資源文件的在服務器中的絕對路徑

ARM7探究

不同的 不同 face 數據 pro 通用 http 定義 指令 1.流水線:三級流水線 預取、譯碼、執行。三級並行發生 2.什麽是哈佛結構? 哈佛結構是一種存儲器結構,是一種並行體系結構,它的主要特點是將程序和數據存儲在不同的存儲空間中,即程序存儲器和數據存儲器是兩個