你真的不需要担心。 Python 不会像仅仅 600 个单词那样占用内存。
稍加注意,您可以直接测量内存需求。 sys.getsizeof() function 可让您测量给定 Python 对象的直接内存需求(仅直接内存,而不是它引用的任何内容!)。您可以使用它来测量单个字符串:
>>> import sys
>>> sys.getsizeof("Hello!")
55
>>> sys.getsizeof("memoryfootprint")
64
具体大小取决于 Python 版本和您的操作系统。 Python 字符串对象需要基本内存量来存储大量簿记信息,然后每个字符需要 1、2 或 4 个字节,具体取决于最高 Unicode 代码点。对于 ASCII,每个字母只有一个字节。 Python 3.7,在我的 Mac OS X 系统上使用 49 个字节作为簿记部分。
获取 Python list 对象的大小意味着您得到只是列表对象内存要求,而不是存储在“列表”中的任何内容。您可以重复将相同的对象添加到列表中,但不会得到副本,因为Python uses references for everything,包括列表内容。考虑到这一点。
让我们加载 300 个随机单词,并创建两个列表,看看内存需要什么:
>>> import random
>>> words = list(map(str.strip, open('/usr/share/dict/words'))) # big file of words, present on many computers
>>> words = random.sample(words, 300) # just use 300
>>> words[:10]
['fourer', 'tampon', 'Minyadidae', 'digallic', 'euploid', 'Mograbi', 'sketchbook', 'annul', 'ambilogy', 'outtalent']
>>> import statistics
>>> statistics.mean(map(len, words))
9.346666666666666
>>> statistics.median(map(len, words))
9.0
>>> statistics.mode(map(len, words))
10
>>> sys.getsizeof(words)
2464
>>> sum(sys.getsizeof(word) for word in words)
17504
这是一个列表,包含 300 个唯一单词,平均长度刚刚超过 9 个字符,列表需要 2464 个字节,单词本身需要 17504 个字节。这甚至不到 20KB。
但是,您说,您有 2 个列表。但是第二个列表不会包含您的单词的副本,这只是对现有单词的更多引用,因此只需要另外 2464 个字节,即 2KB。
对于 300 个随机英文单词,在两个列表中,您的总内存需求约为 20KB 内存。
在 8GB 机器上,您不会有任何问题。请注意,我将整个 words 文件一次性加载到我的计算机中,然后将其缩减为 300 个随机单词。这是整个初始列表需要多少内存:
>>> words = list(map(str.strip, open('/usr/share/dict/words')))
>>> len(words)
235886
>>> sum(sys.getsizeof(word) for word in words)
13815637
>>> sys.getsizeof(words)
2007112
这大约是 15MB 的内存,用于将近 236,000 个单词。
如果您担心具有更多对象的大型程序,您也可以使用tracemalloc library 获取有关内存使用的统计信息:
last = None
def display_memory_change(msg):
global last
snap = tracemalloc.take_snapshot()
statdiff, last = snap.compare_to(last, 'filename', True), snap
tot = sum(s.size for s in statdiff)
change = sum(s.size_diff for s in statdiff)
print('{:>20} (Tot: {:6.1f} MiB, Inc: {:6.1f} MiB)'.format(
msg, tot / 2 ** 20, change / 2 ** 20))
# at the start, get a baseline
tracemalloc.start()
last = tracemalloc.take_snapshot()
# create objects, run more code, etc.
display_memory_change("Some message as to what has been done")
# run some more code.
display_memory_change("Show some more statistics")
使用上面的代码来衡量阅读所有这些单词:
tracemalloc.start()
last = tracemalloc.take_snapshot()
display_memory_change("Baseline")
words = list(map(str.strip, open('/usr/share/dict/words')))
display_memory_change("Loaded words list")
输出
Baseline (Tot: 0.0 MiB, Inc: 0.0 MiB)
Loaded words list (Tot: 15.1 MiB, Inc: 15.1 MiB)
确认我的sys.getsizeof() 测量结果。