[Python-ideas] String and bytes bitwise operations
Terry Reedy
tjreedy at udel.edu
Fri Jun 22 12:25:53 EDT 2018
On 6/22/2018 7:08 AM, INADA Naoki wrote:
> Bitwise xor is used for "masking" code like these:
>
> https://github.com/PyMySQL/PyMySQL/blob/37eba60439039eff17b32ef1a63b45c25ea28cec/pymysql/connections.py#L139-L146
This points to a function _my_crypt that is O(n*n) because of using
bytes.append. Using bytearray.append makes it O(n).
---
import random
import struct
import timeit
range_type = range
def _my_crypt(message1, message2):
length = len(message1)
result = b''
for i in range_type(length):
x = (struct.unpack('B', message1[i:i+1])[0] ^
struct.unpack('B', message2[i:i+1])[0])
result += struct.pack('B', x)
return result
def _my_crypt2(message1, message2):
length = len(message1)
result = bytearray()
for i in range_type(length):
x = (struct.unpack('B', message1[i:i+1])[0] ^
struct.unpack('B', message2[i:i+1])[0])
result += struct.pack('B', x)
return bytes(result)
def make(n):
result = bytearray()
for i in range(n):
result.append(random.randint(0, 255))
return result
for m in (10, 100, 1000, 10_000, 100_000, 1000_000):
m1 = make(m)
m2 = make(m)
n = 1000_000 // m
print(f'bytes len {m}, timeit reps {n}')
print('old ', timeit.timeit('_my_crypt(m1, m2)', number = n,
globals=globals()))
print('new ', timeit.timeit('_my_crypt2(m1, m2)', number = n,
globals=globals()))
---
prints
bytes len 10, timeit reps 100000
old 1.2277594129999998
new 1.2174212309999999
bytes len 100, timeit reps 10000
old 1.145566423
new 1.0924002120000003
bytes len 1000, timeit reps 1000
old 1.2860306190000002
new 1.1168685839999999
bytes len 10000, timeit reps 100
old 1.6543344650000003
new 1.118191714
bytes len 100000, timeit reps 10
old 4.2568492110000005
new 1.1266137560000011
bytes len 1000000, timeit reps 1
old 60.651238144000004
new 1.1315020199999992
I tried to submit this to https://github.com/PyMySQL/PyMySQL/issues/new
but [Submit] does not work for me.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list