作为处理一个能容纳数千万或数亿个键的数据集的优化,我真的非常非常想预先调整它的容量.但似乎没有毕达通的方法来做到这一点。
使用Cython或C标注直接调用CPython的内部函数(如二分体()或NewPresized() )来实现这一点是否实用?
发布于 2015-05-29 02:30:31
这取决于你所说的实际意义。这当然很简单;您只需调用_PyDict_NewPresized(howevermany)即可。见鬼,你甚至可以通过Python来完成这个任务:
>>> import ctypes
>>> import sys
>>> ctypes.pythonapi._PyDict_NewPresized.restype = ctypes.py_object
>>> d = ctypes.pythonapi._PyDict_NewPresized(100)
>>> sys.getsizeof(d)
1676
>>> sys.getsizeof({})
140
>>> len(d)
0正如您所看到的,dict是预先设定的,但是它没有元素。像这样的CPython实现细节是否实用取决于您。
发布于 2015-05-29 04:19:53
经过一个晚上的黑客攻击,我想出了以下解决方案,它不依赖于任何模块。它允许您为任意数量的元素( 2**31-1 (=2,147,483,647)进行初始化。
def bigdict(size):
bytecode = '\x91%c%ci%c%cS'%((size>>16)&0xff,(size>>24)&0xff,size&0xff,(size>>8)&0xff)
return eval(bigdict.func_code.__class__( 0, 0, 1, 64, bytecode, (), (), (), "317070", '<module>', 1, '', (), ()))作为一个例子:
In [95]: print sys.getsizeof({})
280
In [96]: print sys.getsizeof(bigdict(0))
280
In [97]: print sys.getsizeof(bigdict(1))
280
In [98]: print sys.getsizeof(bigdict(100))
3352
In [99]: print sys.getsizeof(bigdict(2**29-1))
12884902168
In [100]: print bigdict(2**29-1)
{}这是我见过的最慢的空话。最后的命令需要很长时间才能完成。
发布于 2015-05-29 01:44:20
一般来说,这是个坏主意,因为这意味着您的代码依赖于python语言的实现。因此,每次更新CPython时,它都可能中断。但是,如果预先知道键(可能不会扩展到python的其他实现),就可以在CPython中预先调整dict的大小:
keys = {'red', 'green', 'blue', 'yellow', 'orange', 'pink', 'black'}
d = dict.fromkeys(keys)这个dict d 马上就有正确的尺寸,因为dict.fromkeys()预先分配空间。
https://stackoverflow.com/questions/30519600
复制相似问题