If the bytearray is empty and a uniquely referenced bytes object is
being concatenated (ex. one just recieved from read), just use its
storage as the backing for the bytearray rather than copying it.
build_bytes_unique: Mean +- std dev: [base] 383 ns +- 11 ns -> [iconcat_opt] 342 ns +- 5 ns: 1.12x faster
build_bytearray: Mean +- std dev: [base] 496 ns +- 8 ns -> [iconcat_opt] 471 ns +- 13 ns: 1.05x faster
encode: Mean +- std dev: [base] 482 us +- 2 us -> [iconcat_opt] 13.8 us +- 0.1 us: 34.78x faster
Benchmark hidden because not significant (1): build_bytes
Geometric mean: 2.53x faster
note: Performance of build_bytes is expected to stay constant.
```python
import pyperf
runner = pyperf.Runner()
count1 = 1_000
count2 = 100
count3 = 10_000
CHUNK_A = b'a' * count1
CHUNK_B = b'b' * count2
CHUNK_C = b'c' * count3
def build_bytes():
# Bytes not uniquely referenced.
ba = bytearray()
ba += CHUNK_A
ba += CHUNK_B
ba += CHUNK_C
def build_bytes_unique():
ba = bytearray()
# Repeat inline results in uniquely referenced bytes.
ba += b'a' * count1
ba += b'b' * count2
ba += b'c' * count3
def build_bytearray():
# Each bytearray appended is uniquely referenced.
ba = bytearray()
ba += bytearray(CHUNK_A)
ba += bytearray(CHUNK_B)
ba += bytearray(CHUNK_C)
runner.bench_func('build_bytes', build_bytes)
runner.bench_func('build_bytes_unique', build_bytes_unique)
runner.bench_func('build_bytearray', build_bytearray)
runner.timeit(
name="encode",
setup="a = 'a' * 1_000_000",
stmt="bytearray(a, encoding='utf8')")
```