如何避免子字符串
我现在处理字符串的某些部分是这样做的:
for (i, j) in huge_list_of_indices:
process(huge_text_block[i:j])
我想避免生成这些临时子字符串带来的额外开销。有没有什么好主意?也许可以用某种方式利用索引偏移的包装器?这目前是我的瓶颈。
注意,process() 是另一个需要字符串作为输入的 Python 模块。
编辑:
有些人怀疑这是否真的是个问题。这里有一些示例结果:
import time
import string
text = string.letters * 1000
def timeit(fn):
t1 = time.time()
for i in range(len(text)):
fn(i)
t2 = time.time()
print '%s took %0.3f ms' % (fn.func_name, (t2-t1) * 1000)
def test_1(i):
return text[i:]
def test_2(i):
return text[:]
def test_3(i):
return text
timeit(test_1)
timeit(test_2)
timeit(test_3)
输出:
test_1 took 972.046 ms
test_2 took 47.620 ms
test_3 took 43.457 ms
6 个回答
1
如果你在使用Python3,可以利用协议缓冲区和内存视图。假设这些文本存储在你的文件系统中的某个地方:
f = open(FILENAME, 'rb')
data = bytearray(os.path.getsize(FILENAME))
f.readinto(data)
mv = memoryview(data)
for (i, j) in huge_list_of_indices:
process(mv[i:j])
另外,你可以看看这篇文章,可能会对你有帮助。
3
是的,使用索引偏移量来包装一个内存映射对象是可行的。
不过在你这么做之前,确定一下生成这些子字符串真的是个问题吗?在你搞清楚时间和内存到底花在哪里之前,不要急着优化。我觉得这应该不是个大问题。
8
我觉得你想要的东西是 缓冲区。
缓冲区的特点是,它们可以“切片”一个支持缓冲区接口的对象,而不需要复制它的内容,实际上是打开了一个“窗口”,可以看到切片对象的内容。想了解更技术性的解释,可以点击 这里。以下是一个摘录:
用C语言实现的Python对象可以导出一组叫做“缓冲区接口”的函数。这些函数可以让对象以原始的、字节为基础的格式暴露它的数据。对象的使用者可以通过缓冲区接口直接访问对象的数据,而不需要先复制一份。
在你的情况下,代码大概应该是这样的:
>>> s = 'Hugely_long_string_not_to_be_copied'
>>> ij = [(0, 3), (6, 9), (12, 18)]
>>> for i, j in ij:
... print buffer(s, i, j-i) # Should become process(...)
Hug
_lo
string
希望对你有帮助!