Skip to content

Instantly share code, notes, and snippets.

@altendky
Created January 11, 2018 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save altendky/ff5ccee2baf9822dce69ae8aa66a0fdf to your computer and use it in GitHub Desktop.
Save altendky/ff5ccee2baf9822dce69ae8aa66a0fdf to your computer and use it in GitHub Desktop.
import textwrap
import timeitrunner
def old(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf)
def new(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
write = fdst.write
if hasattr(fsrc, 'readinto') and length > 0:
buf = memoryview(bytearray(length))
readinto = fsrc.readinto
while 1:
recv_len = readinto(buf)
if recv_len < length:
# write remaining content if any.
write(buf[:recv_len])
break
write(buf)
else:
read = fsrc.read
while 1:
buf = read(length)
if not buf:
break
write(buf)
if __name__ == '__main__':
setup = textwrap.dedent('''\
import io
a = io.BytesIO(bytearray([0] * {n} * 1024))
from main import old, new
''')
for kb, cycles in ((1, 2000), (1_000, 20), (10_000, 5)):
print(' - {kb}kb (cycles={cycles})'.format(kb=kb, cycles=cycles))
runner = timeitrunner.Runner(
examples=(
timeitrunner.Example(statement='b = io.BytesIO(); old(a, b)'),
timeitrunner.Example(statement='b = io.BytesIO(); new(a, b)'),
),
repeats=3,
cycles=cycles,
setup=setup.format(n=kb),
)
runner.run()
print(runner.tabulate())
import timeit
import attr
@attr.s(frozen=True)
class Example:
statement = attr.ib()
@attr.s
class Runner:
examples = attr.ib()
setup = attr.ib(default='')
repeats = attr.ib(default=3)
cycles = attr.ib(default=1000)
results = attr.ib(default=attr.Factory(dict))
def run(self):
for example in self.examples:
self.results[example] = min(timeit.repeat(
stmt=self.setup + '\n' + example.statement,
repeat=self.repeats,
number=self.cycles,
))
def tabulate(self):
minimum = min(self.results.values())
lines = []
for example in sorted(self.examples, key=lambda e: self.results[e]):
lines.append('{percent:5}% {statement}'.format(
percent=round(100 * self.results[example] / minimum),
statement=example.statement,
))
return '\n'.join(lines)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment