python - how do I clear a stringio object? -
i have stringio object created , has text in it. i'd clear existing values , reuse instead of recalling it. there anyway of doing this?
tl;dr
don't bother clearing it, create new one—it’s faster.
the method
python 2
here's how find such things out:
>>> stringio import stringio >>> dir(stringio) ['__doc__', '__init__', '__iter__', '__module__', 'close', 'flush', 'getvalue', 'isatty', 'next', 'read', 'readline', 'readlines', 'seek', 'tell', 'truncate', 'write', 'writelines'] >>> help(stringio.truncate) on method truncate in module stringio: truncate(self, size=none) unbound stringio.stringio method truncate file's size. if optional size argument present, file truncated (at most) size. size defaults current position. current file position not changed unless position beyond new file size. if specified size exceeds file's current size, file remains unchanged.
so, want .truncate(0)
. it's cheaper (and easier) initialise new stringio. see below benchmarks.
python 3
(thanks tstone2077 pointing out difference.)
>>> io import stringio >>> dir(stringio) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '_checkclosed', '_checkreadable', '_checkseekable', '_checkwritable', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'getvalue', 'isatty', 'line_buffering', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines'] >>> help(stringio.truncate) on method_descriptor: truncate(...) truncate size pos. pos argument defaults current file position, returned tell(). current file position unchanged. returns new absolute position.
it important note the current file position unchanged, whereas truncating size 0 reset position in python 2 variant.
thus, python 2, need
>>> cstringio import stringio >>> s = stringio() >>> s.write('foo') >>> s.getvalue() 'foo' >>> s.truncate(0) >>> s.getvalue() '' >>> s.write('bar') >>> s.getvalue() 'bar'
if in python 3, won't result expected:
>>> io import stringio >>> s = stringio() >>> s.write('foo') 3 >>> s.getvalue() 'foo' >>> s.truncate(0) 0 >>> s.getvalue() '' >>> s.write('bar') 3 >>> s.getvalue() '\x00\x00\x00bar'
so in python 3 need reset position:
>>> cstringio import stringio >>> s = stringio() >>> s.write('foo') 3 >>> s.getvalue() 'foo' >>> s.truncate(0) 0 >>> s.seek(0) 0 >>> s.getvalue() '' >>> s.write('bar') 3 >>> s.getvalue() 'bar'
if using truncate
method in python 2 code, it's safer call seek(0)
@ same time (before or after, doesn't matter) code won't break when inevitably port python 3. , there's reason why should create new stringio
object!
times
python 2
>>> timeit import timeit >>> def truncate(sio): ... sio.truncate(0) ... return sio ... >>> def new(sio): ... return stringio() ...
when empty, stringio:
>>> stringio import stringio >>> timeit(lambda: truncate(stringio())) 3.5194039344787598 >>> timeit(lambda: new(stringio())) 3.6533868312835693
with 3kb of data in, stringio:
>>> timeit(lambda: truncate(stringio('abc' * 1000))) 4.3437709808349609 >>> timeit(lambda: new(stringio('abc' * 1000))) 4.7179079055786133
and same cstringio:
>>> cstringio import stringio >>> timeit(lambda: truncate(stringio())) 0.55461597442626953 >>> timeit(lambda: new(stringio())) 0.51241087913513184 >>> timeit(lambda: truncate(stringio('abc' * 1000))) 1.0958449840545654 >>> timeit(lambda: new(stringio('abc' * 1000))) 0.98760509490966797
so, ignoring potential memory concerns (del oldstringio
), it's faster truncate stringio.stringio
(3% faster empty, 8% faster 3kb of data), it's faster ("fasterer" too) create new cstringio.stringio
(8% faster empty, 10% faster 3kb of data). i'd recommend using easiest one—so presuming you're working cpython, use cstringio
, create new ones.
python 3
the same code, seek(0)
put in.
>>> def truncate(sio): ... sio.truncate(0) ... sio.seek(0) ... return sio ... >>> def new(sio): ... return stringio() ...
when empty:
>>> io import stringio >>> timeit(lambda: truncate(stringio())) 0.9706327870007954 >>> timeit(lambda: new(stringio())) 0.8734330690022034
with 3kb of data in:
>>> timeit(lambda: truncate(stringio('abc' * 1000))) 3.5271066290006274 >>> timeit(lambda: new(stringio('abc' * 1000))) 3.3496507499985455
so python 3 creating new 1 instead of reusing blank 1 11% faster , creating new 1 instead of reusing 3k 1 5% faster. again, create new stringio
rather truncating , seeking.
Comments
Post a Comment