【问题标题】:Is there away to allocate memory to a long string in python?是否可以在 python 中为长字符串分配内存?
【发布时间】:2022-01-12 13:10:21
【问题描述】:

我正在处理递归连接到大约 8000 万个字符长度的字符串。随着字符串长度的增加,Python 的速度会急剧下降。

考虑以下循环:

s = ''
for n in range(0,r):
  s += 't'

我测量运行时间为 r = 800,000 时为 86 毫秒,r = 8,000,000 时为 3.11 秒,r = 80,000,000 时为 222 秒

我猜这与 python 如何为字符串分配额外的内存有关。有没有办法加快这个速度,比如在声明字符串 s 的时候分配完整的 80MB?

【问题讨论】:

  • 使用list,附加各个字符串,然后''.join在末尾​​span>
  • 或者,使用 bytearraybytes
  • 不要在字符串上使用+,这是低效的。在列表中使用' '.join()。或者对于你的例子r * 't' 会做的伎俩

标签: python string memory-management


【解决方案1】:

当你有一个字符串值并在你的程序中改变它时,之前的值将保留在内存的一部分中,而改变的字符串将被放置在 RAM 的新部分中。

因此,RAM 中的旧值仍未使用。

为此,使用垃圾收集器并从旧的、未使用的值中清除您的 RAM,但这需要时间。

你可以自己做。您可以使用 gc 模块查看对象的不同代请参阅:

import gc
print(gc.get_threshold())

结果:

(596, 2, 1)

在这个例子中,我们在最年轻的一代中有 596 个对象,在下一代中有两个对象,在最老的一代中有一个对象。 因此,分配速度可能会很慢,您的程序可能会变慢

use this link to efficient String Concatenation in Python

祝你好运。

【讨论】:

  • 这里不涉及gc垃圾回收器
  • 那篇文章正是我所需要的。我最终选择了 StringIO,对于 80,000,000 的字符串长度,它的速度提高了大约 70 倍。
【解决方案2】:

它不能以直接的方式使用文本(字符串)对象来完成,但如果您正在处理字节,它是微不足道的 - 在这种情况下,您可以创建一个大于最终结果的 bytearray 对象并插入您的价值观。

如果您需要最终的对象作为文本,您可以将其解码为文本,单步将足够快。

由于您没有说明数据的性质,它可能会变得更难 - 如果没有单字节编码可以覆盖您需要的所有字符,您必须求助于可变长度编码,例如 utf -8,或多字节编码,例如 utf-16 或 32。在这两种情况下,如果您正确跟踪插入索引,则没有问题 - 这也是您重新编码的最终数据大小。 (如果你使用的是遗传的“GATACA”字符串,只需使用 ASCII 编码,你就完成了)

data = bytearray(100_000_000) # 100 million positions - 
index = 0
for character in input_data:
    v = character.encode("utf-8")
    s = len(v)
    if s == 1:
        data[index] = v
    else:
        data[index: index + len(v)] = v
    index += len(v)
data_as_text = data[:index].decode("utf-8")

【讨论】:

    猜你喜欢
    • 2022-06-11
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多