Python缓冲区复制速度 - 为什么数组比字符串慢?

Cor*_*rey 6 python arrays string performance stdvector

我在C++中有一个继承自的缓冲区对象std::vector<char>.我想将此缓冲区转换为Python字符串,以便我可以通过Twisted的protocol.transport.write通过网络将其发送出去.

我想到的两种方法是:(1)创建一个字符串并用char填充它:

def scpychar(buf, n):
    s = ''
    for i in xrange(0, n):
        s += buf[i]
    return s
Run Code Online (Sandbox Code Playgroud)

(2)制作一个char数组(因为我知道缓冲区有多大),填充它并将其转换为字符串

def scpyarr(buf, n):
    a = array.array('c','0'*n)
    for i in xrange(0, n):
        a[i] = buf[i]
    return a.tostring()
Run Code Online (Sandbox Code Playgroud)

我原以为(1)每次s += buf[i]调用时都必须创建一个新的字符串对象,并复制旧字符串的内容.所以我期待(2)比(1)更快.但是,如果我使用timeit测试它,我发现(1)实际上大约是(2)的两倍.

我想知道是否有人可以解释为什么(1)更快?

奖励指向更有效的方式从a std::vector<char>字符串转换为Python字符串.

use*_*ica 3

如果CPython 可以确定没有人保留对旧字符串的引用,它有时可以将字符串优化+=为就地。算法(1)可能触发了优化,因此它不会遭受原本应有的二次运行时间。但是,无法保证此行为,并且其他 Python 实现可能不支持它。

尝试

''.join(buf)
Run Code Online (Sandbox Code Playgroud)

与 (1) 不同,它应该在任何 Python 实现上提供线性时间性能,并且比 (2) 更快。