python的一些性能上的细节

1.合并拼接字符串

你想将几个小的字符串合并为一个大的字符串
解决方案
若是你想要合并的字符串是在一个序列或者 iterable 中,那么最快的方式就是使用
join() 方法。好比:
>>> parts = ['Is', 'Chicago', 'Not', 'Chicago?']
>>> ' '.join(parts)
'Is Chicago Not Chicago?'
>>> ','.join(parts)
'Is,Chicago,Not,Chicago?'
>>> ''.join(parts)
'IsChicagoNotChicago?'
>>>
初看起来,这种语法看上去会比较怪,可是 join() 被指定为字符串的一个方法。 这样作
的部分缘由是你想去链接的对象可能来自各类不一样的数据序列(好比列表,元组,字典,
文件,集合或生成器等), 若是在全部这些对象上都定义一个 join() 方法明显是冗余
的。 所以你只须要指定你想要的分割字符串并调用他的 join() 方法去将文本片断组合起
来。
若是你仅仅只是合并少数几个字符串,使用加号(+)一般已经足够了:
>>> a = 'Is Chicago'
>>> b = 'Not Chicago?'
>>> a + ' ' + b
'Is Chicago Not Chicago?'
>>>
加号(+)操做符在做为一些复杂字符串格式化的替代方案的时候一般也工做的很好,比
如:
>>> print('{} {}'.format(a,b))
Is Chicago Not Chicago?
>>> print(a + ' ' + b)
Is Chicago Not Chicago?
>>>
若是你想在源码中将两个字面字符串合并起来,你只须要简单的将它们放到一块儿,不须要
用加号(+)。好比:
>>> a = 'Hello' 'World'
>>> a
'HelloWorld'
>>>
讨论
字符串合并可能看上去并不须要用一整节来讨论。 可是不该该小看这个问题,程序员通
常在字符串格式化的时候由于选择不当而给应用程序带来严重性能损失。
最重要的须要引发注意的是,当咱们使用加号(+)操做符去链接大量的字符串的时候是非
常低效率的, 由于加号链接会引发内存复制以及垃圾回收操做。 特别的,你永远都不该
像下面这样写字符串链接代码:
s = ''
for p in parts:
    s += p
这种写法会比使用 join() 方法运行的要慢一些,由于每一次执行+=操做的时候会建立一
个新的字符串对象。 你最好是先收集全部的字符串片断而后再将它们链接起来。
一个相对比较聪明的技巧是利用生成器表达式(参考1.19小节)转换数据为字符串的同时合
并字符串,好比:
>>> data = ['ACME', 50, 91.1]
>>> ','.join(str(d) for d in data)
'ACME,50,91.1'
>>>
一样还得注意没必要要的字符串链接操做。有时候程序员在没有必要作链接操做的时候仍然
画蛇添足。好比在打印的时候:
print(a + ':' + b + ':' + c) # Ugly
print(':'.join([a, b, c])) # Still ugly
print(a, b, c, sep=':') # Better
当混合使用I/O操做和字符串链接操做的时候,有时候须要仔细研究你的程序。 好比,考
虑下面的两端代码片断:
# Version 1 (string concatenation)
f.write(chunk1 + chunk2)
# Version 2 (separate I/O operations)
f.write(chunk1)
f.write(chunk2)
若是两个字符串很小,那么第一个版本性能会更好些,由于I/O系统调用天生就慢。 另外
一方面,若是两个字符串很大,那么第二个版本可能会更加高效, 由于它避免了建立一
个很大的临时结果而且要复制大量的内存块数据。 仍是那句话,有时候是须要根据你的
应用程序特色来决定应该使用哪一种方案。程序员

若是你准备编写构建大量小字符串的输出代码, 你最好考虑下使用生成器
函数,利用yield语句产生输出片断。好比:
def sample():
    yield 'Is'
    yield 'Chicago'
    yield 'Not'
    yield 'Chicago?app

这种方法一个有趣的方面是它并无对输出片断到底要怎样组织作出假设。 例如,你可
以简单的使用 join() 方法将这些片断合并起来:
text = ''.join(sample())
或者你也能够将字符串片断重定向到I/O:
for part in sample():
    f.write(part)函数

再或者你还能够写出一些结合I/O操做的混合方案:
def combine(source, maxsize):
    parts = []
    size = 0
    for part in source:
        parts.append(part)
        size += len(part)
        if size > maxsize:
            yield ''.join(parts)
            parts = []
            size = 0
        yield ''.join(parts)
# 结合文件操做
with open('filename', 'w') as f:
    for part in combine(sample(), 32768):
        f.write(part)性能

这里的关键点在于原始的生成器函数并不须要知道使用细节,它只负责生成字符串片断就
行了。
 spa

相关文章
相关标签/搜索