1. 程式人生 > >為啥我的Python這麼慢 (一)

為啥我的Python這麼慢 (一)

長假結束了,這不痛苦。痛苦的是長假結束了,發現寫的基因組讀取程式還沒執行完?

Python系列教程中,我們提到一個概念字串是不可修改的。這一點可以通過id函式來判斷確實是對的。但是這個概念會對我們寫作程式有什麼影響一直沒有特別深的理解。

直到有一次,實驗室一個朋友要讀基因組資料,結果發現3 G的基因組讀一晚上都沒讀完,就很詫異,看了下程式碼,這麼寫的。

基因組序列是GRCh38.faFASTA格式,序列行每行70個字元,共44,284,892行 (記住行數有多大),示例如下。

>chr1
NNNNN...(60個N)...NNNNN
ACGTA...(60個Nt)...ACGTA
...
>chr2 NNNNN...(60個N)...NNNNN ACGTA...(60個Nt)...ACGTA ...

讀取程式如下(這裡只選了讀取基因組的部分,點選檢視更多FASTA的操作):

aDict = {}
for line in open("GRCh38.fa"):
    if line[0] == '>':
        key = line[1:-1]
        aDict[key] = ''
    else:
        aDict[key]+=line.strip()

程式看上去沒問題,獲取id,讀取一行附加在前一行後面,邏輯是對的。然後執行上程式,回去睡覺,滿心歡喜期待第二天早上出來獲得結果,結果啥也沒出來,程式還停留在讀取基因組序列步驟。

按我們伺服器的效能,這不應該啊。就看程式碼是不是出問題了,怎麼看邏輯都對。後來就想會不會是序列累加的問題,就換了一個寫法。程式碼稍微長了些,先存入列表,再連線起來。

Dict = {}
for line in open("GRCh38.fa"):
    if line[0] == '>':
        key = line[1:-1]
        aDict[key] = []
    else:
        aDict[key].append(line.strip())
#--------------------------------
for key, value in
aDict.items(): aDict[key] = ''.join(value)

使用time函式,檢視下執行速度,不足1分鐘。time及更多程式監測方法見命令執行監測和軟體安裝

time readFaJoin.py 

real    0m51.256s
user    0m40.729s
sys 0m10.425s

不比不知道,一比嚇一跳;速度差了何止幾千倍。

這時,我們重新理解下什麼叫字串不可修改。

使用id函式來確定字串累加跟列表累加的不同。(不同電腦或不同時間允許的id不同,不看具體數字,只看id的變化)

ehbio = "Sheng Xin Bao Dian"
id(ehbio)

## Output: 140405359946640

ehbio += ' very good'
ehbio

## Output: 'Sheng Xin Bao Dian very good'

id(ehbio)

## Output: 140405344262576

同樣的變數名字,但不同的id。就是說python在對變數ehbio新增字串時,是先開闢一份記憶體空間,把ehbio原有內容加新內容組成的字串存入新的記憶體空間。而不是想象中的直接追加在已有字串的後面。這樣對4千萬行資料的操作就是要做4千萬次的記憶體空間開闢和字串儲存。這是一個特別耗時的步驟。

而如果是一個列表呢?

aList = ['Sheng','Xin']

id(aList)

## Output: 140405344245520

aList.append("Bao")

id(aList)

## Output: 140405344245520

aList.extend(["Dian", "excellent"])

id(aList)

## Output: 140405344245520

而列表就不一樣了,無論是使用append增加一個元素,還是使用extend增加一組元素,列表變數aListid都沒有變化。說明這是追加,不是新建。

Python使用中還有不少類似這樣的需要注意的小細節,在後續會陸續推出。

而且我們生信寶典團隊要開培訓班了,涉及Linux系統操作Python程式設計R Cytoscape作圖高通量資料分析。如果您有需要我們解決的問題,還請後臺留言,一併納入培訓班的授課。希望通過我們的努力,讓培訓發揮作用,不管是來學技術,來學理念,還是來解決你手頭棘手的問題,希望都能有所收穫。

具體日期靜待公佈。