Python何时为相同的字符串分配新内存?
两个具有相同字符的Python字符串,a == b,可以共享内存,id(a)== id(b),或者可以在内存中两次,id(a)!= id(b)。尝试
ab = "ab"print id( ab ), id( "a"+"b" )
在这里,Python认识到新创建的“a”+“b”与已经在内存中的“ab”相同 - 不错。
现在考虑一个N长的州名列表[“亚利桑那州”,“阿拉斯加”,“阿拉斯加”,“加利福尼亚”......](在我的案例中为N~500000)。
我看到50个不同的id()s⇒每个字符串“Arizona”......只存储一次,很好。
但是将列表写入磁盘并再次读回:“相同”列表现在有N个不同的id()s,内存更多,见下文。
怎么 - 任何人都可以解释Python字符串内存分配?
""" when does Python allocate new memory for identical strings ? ab = "ab" print id( ab ), id( "a"+"b" ) # same ! list of N names from 50 states: 50 ids, mem ~ 4N + 50S, each string once but list > file > mem again: N ids, mem ~ N * (4 + S) """from __future__ import divisionfrom collections import defaultdictfrom copy import copyimport cPickleimport randomimport sys states = dict(AL = "Alabama",AK = "Alaska",AZ = "Arizona",AR = "Arkansas",CA = "California",CO = "Colorado",CT = "Connecticut",DE = "Delaware",FL = "Florida",GA = "Georgia",)def nid(alist): """ nr distinct ids """ return "%d ids %d pickle len" % ( len( set( map( id, alist ))), len( cPickle.dumps( alist, 0 ))) # rough est ?# cf http://stackoverflow.com/questions/2117255/python-deep-getsizeof-list-with-contentsN = 10000exec( "\n".join( sys.argv[1:] )) # var=val ...random.seed(1) # big list of random names of states --names = []for j in xrange(N): name = copy( random.choice( states.values() )) names.append(name)print "%d strings in mem: %s" % (N, nid(names) ) # 10 ids, even with copy()
添加25jan:
Python内存(或任何程序)中有两种字符串:
Ustrings,在一个独特字符串的Ucache中:这些节省内存,如果两者都在Ucache中,则快速== b
Ostrings,其他,可以存储任意次数。
intern(astring)
在Ucache中放入astring(Alex +1); 除此之外我们对Python如何将Ostrings移动到Ucache一无所知 - “ab”之后“a”+“b”是如何进入的?(“来自文件的字符串”毫无意义 - 没有办法知道。)
简而言之,Ucaches(可能有几个)仍然是模糊的。
一个历史脚注: SPITBOL 统一所有字符串ca. 1970年。
拉莫斯之舞
繁华开满天机
慕虎7371278
相关分类