Python:';拆封';长XOR';d数据串

Python:';拆封';长XOR';d数据串,python,performance,websocket,xor,Python,Performance,Websocket,Xor,作为的一部分,所有客户端发送的帧必须使用4字节掩码对帧的有效负载部分进行掩码。在C++中,这将是非常容易的: for (size_t i = 0; i < length; i++) { data[i] ^= mask[i % 4]; } 所以经过一些研究,我发现了这个: m = itertools.cycle(mask) frame = ''.join(chr(ord(x) ^ ord(y)) for (x,y) in itertools.izip(oldFrame, m))

作为的一部分,所有客户端发送的帧必须使用4字节掩码对帧的有效负载部分进行掩码。在C++中,这将是非常容易的:

for (size_t i = 0; i < length; i++) {
    data[i] ^= mask[i % 4];
}
所以经过一些研究,我发现了这个:

m = itertools.cycle(mask)
frame = ''.join(chr(ord(x) ^ ord(y)) for (x,y) in itertools.izip(oldFrame, m))
在CPython,这将解密所需的时间减少了一半。在PyPy中,对于16MB屏蔽字符串,这很容易增加到1.5GB的RAM使用量,之后它开始交换,我必须杀死它。CPython对这个16MB字符串“仅”使用150MB内存(需要20秒),但这仍然很糟糕。相比之下,我的C++基准测试在0.05秒内完成,没有内存开销。 当然,这些极端情况在软件进入生产模式后不会发生(所有传入的数据都限制在10KB),但我真的希望在这个基准上有一个好的分数

有什么想法吗?唯一的要求是:在CPython和PyPy上都很快,并且内存使用率很低。原始字符串不必保留

一些测试代码适用于那些想要进行实验的人:

import os, time

frame = os.urandom(16 << 20)
mask = os.urandom(4)

def unmask(oldFrame, mask):
    # Do your magic
    return newFrame

for i in range(0, 3): # Run several times, to help PyPy's JIT compiler
    startTime = time.time()
    f = unmask(frame, mask)
    endTime = time.time()
    print 'This run took %.3f seconds' % (endTime - startTime)
导入操作系统,时间
frame=os.uradom(16改用a,它是可变的


您也可以考虑NUMPY,它允许您将操作卸载到NUMPY中的有效C代码。这是一个使用NoMIP不支持的较慢方法的后退,它使用支持可变字节数组的数组模块。

import os, time

frame = os.urandom(16 << 20)
mask = os.urandom(4)

def unmask(oldFrame, mask):
    # Do your magic
    return newFrame

for i in range(0, 3): # Run several times, to help PyPy's JIT compiler
    startTime = time.time()
    f = unmask(frame, mask)
    endTime = time.time()
    print 'This run took %.3f seconds' % (endTime - startTime)
frame = bytearray(frame)
for i in range(len(mask)):
    frame[i] ^= mask[i]