import io
import timeit
from itertools import chain, groupby
chunk_sizes = [5, 11, 1024]
x = (b'x'*25+b'\n')*1000
inputs = [[x[i:i+chunk_size] for i in range(0, len(x), chunk_size)]
for chunk_size in chunk_sizes]
def make_strings(G):
strings = chain.from_iterable(map(bytes.decode, G))
for k, g in groupby(strings, key=lambda c: c not in '\n\r'):
if k:
yield ''.join(g)
class ReadableIterator(io.IOBase):
def __init__(self, it):
self.it = iter(it)
def read(self, n):
# ignore argument, nobody actually cares
# note that it is *critical* that we suppress the `StopIteration` here
return next(self.it, b'')
def readable(self):
return True
for chunk_size, input_chunks in zip(chunk_sizes, inputs):
print(chunk_size)
print(timeit.timeit('list(io.TextIOWrapper(ReadableIterator(iter(input_chunks)), newline=""))',
number=10, globals=globals()))
print(timeit.timeit('list(make_strings(iter(input_chunks)))',
number=10, globals=globals()))
aW1wb3J0IGlvCmltcG9ydCB0aW1laXQKZnJvbSBpdGVydG9vbHMgaW1wb3J0IGNoYWluLCBncm91cGJ5CgpjaHVua19zaXplcyA9IFs1LCAxMSwgMTAyNF0KCnggPSAoYid4JyoyNStiJ1xuJykqMTAwMAppbnB1dHMgPSBbW3hbaTppK2NodW5rX3NpemVdIGZvciBpIGluIHJhbmdlKDAsIGxlbih4KSwgY2h1bmtfc2l6ZSldCiAgICAgICAgICBmb3IgY2h1bmtfc2l6ZSBpbiBjaHVua19zaXplc10KCmRlZiBtYWtlX3N0cmluZ3MoRyk6CiAgICBzdHJpbmdzID0gY2hhaW4uZnJvbV9pdGVyYWJsZShtYXAoYnl0ZXMuZGVjb2RlLCBHKSkKICAgIGZvciBrLCBnIGluIGdyb3VwYnkoc3RyaW5ncywga2V5PWxhbWJkYSBjOiBjIG5vdCBpbiAnXG5ccicpOgogICAgICAgIGlmIGs6CiAgICAgICAgICAgIHlpZWxkICcnLmpvaW4oZykKCmNsYXNzIFJlYWRhYmxlSXRlcmF0b3IoaW8uSU9CYXNlKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBpdCk6CiAgICAgICAgc2VsZi5pdCA9IGl0ZXIoaXQpCiAgICBkZWYgcmVhZChzZWxmLCBuKToKICAgICAgICAjIGlnbm9yZSBhcmd1bWVudCwgbm9ib2R5IGFjdHVhbGx5IGNhcmVzCiAgICAgICAgIyBub3RlIHRoYXQgaXQgaXMgKmNyaXRpY2FsKiB0aGF0IHdlIHN1cHByZXNzIHRoZSBgU3RvcEl0ZXJhdGlvbmAgaGVyZQogICAgICAgIHJldHVybiBuZXh0KHNlbGYuaXQsIGInJykKICAgIGRlZiByZWFkYWJsZShzZWxmKToKICAgICAgICByZXR1cm4gVHJ1ZQoKZm9yIGNodW5rX3NpemUsIGlucHV0X2NodW5rcyBpbiB6aXAoY2h1bmtfc2l6ZXMsIGlucHV0cyk6CiAgICBwcmludChjaHVua19zaXplKQogICAgcHJpbnQodGltZWl0LnRpbWVpdCgnbGlzdChpby5UZXh0SU9XcmFwcGVyKFJlYWRhYmxlSXRlcmF0b3IoaXRlcihpbnB1dF9jaHVua3MpKSwgbmV3bGluZT0iIikpJywKICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyPTEwLCBnbG9iYWxzPWdsb2JhbHMoKSkpCiAgICBwcmludCh0aW1laXQudGltZWl0KCdsaXN0KG1ha2Vfc3RyaW5ncyhpdGVyKGlucHV0X2NodW5rcykpKScsCiAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlcj0xMCwgZ2xvYmFscz1nbG9iYWxzKCkpKQ==