我們通常會(huì)聽說疼邀,在for循環(huán)中要使用range來代替xrange什荣,xrange更能節(jié)省內(nèi)存,先來看一下這兩個(gè)的實(shí)現(xiàn):
def range(start, stop, step=1):
numbers = []
while start < stop:
numbers.append(start)
start += step
return numbers
def xrange(start, stop, step=1):
while start < stop:
yield start
start += stop
- range會(huì)預(yù)先生成范圍內(nèi)所有的整數(shù)锨天,存入一個(gè)List中菊卷,然后返回List缔恳,我們知道List的append的操作是額外消耗內(nèi)存的。
- xrange不會(huì)預(yù)先生成所有的數(shù)字洁闰,通過yield歉甚,每次被請(qǐng)求時(shí),yield只會(huì)生成并返回一個(gè)對(duì)象扑眉,當(dāng)超出range時(shí)纸泄,StopIteration會(huì)拋出赖钞。從內(nèi)存看,一個(gè)N個(gè)元素的loop聘裁,相比xrange雪营,range會(huì)多消耗N倍的內(nèi)存。
- 迭代器咧虎,我們知道loop需要一個(gè)迭代器卓缰,然后不斷調(diào)用next(),知道StopIteration。
- 使用range的流程是:創(chuàng)建一個(gè)完整的List砰诵,返回List,調(diào)用List的iter函數(shù)捌显,返回一個(gè)迭代器茁彭。事實(shí)上,我們只需要一個(gè)迭代器扶歪,但是卻創(chuàng)建了一個(gè)列表...
- 使用xrange的流程是:xrange會(huì)直接返回一個(gè)迭代器理肺。我們可以看到range的流程更為復(fù)雜,做了很多額外的操作善镰,消耗的計(jì)算和內(nèi)存資源更多妹萨。
- 使用range時(shí),這個(gè)預(yù)先分配List內(nèi)存很要命炫欺,比如乎完,range(100000000)會(huì)分配800MB內(nèi)存...對(duì)于一個(gè)C developer來說,嚇?biāo)懒恕?/li>
>>> import sys
>>> a = range(100000000)
>>> sys.getsizeof(a)
800000072
>>>