mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
Issue #22003: When initialized from a bytes object, io.BytesIO() now
defers making a copy until it is mutated, improving performance and memory use on some use cases. Patch by David Wilson.
This commit is contained in:
parent
115171086a
commit
cc66a73d27
4 changed files with 205 additions and 54 deletions
|
@ -9,6 +9,7 @@ from test import support
|
|||
import io
|
||||
import _pyio as pyio
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
class MemorySeekTestMixin:
|
||||
|
||||
|
@ -711,12 +712,57 @@ class CBytesIOTest(PyBytesIOTest):
|
|||
|
||||
@support.cpython_only
|
||||
def test_sizeof(self):
|
||||
basesize = support.calcobjsize('P2nN2Pn')
|
||||
basesize = support.calcobjsize('P2nN2PnP')
|
||||
check = self.check_sizeof
|
||||
self.assertEqual(object.__sizeof__(io.BytesIO()), basesize)
|
||||
check(io.BytesIO(), basesize )
|
||||
check(io.BytesIO(b'a'), basesize + 1 + 1 )
|
||||
check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 )
|
||||
check(io.BytesIO(b'a'), basesize + 1 )
|
||||
check(io.BytesIO(b'a' * 1000), basesize + 1000)
|
||||
|
||||
# Various tests of copy-on-write behaviour for BytesIO.
|
||||
|
||||
def _test_cow_mutation(self, mutation):
|
||||
# Common code for all BytesIO copy-on-write mutation tests.
|
||||
imm = b' ' * 1024
|
||||
old_rc = sys.getrefcount(imm)
|
||||
memio = self.ioclass(imm)
|
||||
self.assertEqual(sys.getrefcount(imm), old_rc + 1)
|
||||
mutation(memio)
|
||||
self.assertEqual(sys.getrefcount(imm), old_rc)
|
||||
|
||||
@support.cpython_only
|
||||
def test_cow_truncate(self):
|
||||
# Ensure truncate causes a copy.
|
||||
def mutation(memio):
|
||||
memio.truncate(1)
|
||||
self._test_cow_mutation(mutation)
|
||||
|
||||
@support.cpython_only
|
||||
def test_cow_write(self):
|
||||
# Ensure write that would not cause a resize still results in a copy.
|
||||
def mutation(memio):
|
||||
memio.seek(0)
|
||||
memio.write(b'foo')
|
||||
self._test_cow_mutation(mutation)
|
||||
|
||||
@support.cpython_only
|
||||
def test_cow_setstate(self):
|
||||
# __setstate__ should cause buffer to be released.
|
||||
memio = self.ioclass(b'foooooo')
|
||||
state = memio.__getstate__()
|
||||
def mutation(memio):
|
||||
memio.__setstate__(state)
|
||||
self._test_cow_mutation(mutation)
|
||||
|
||||
@support.cpython_only
|
||||
def test_cow_mutable(self):
|
||||
# BytesIO should accept only Bytes for copy-on-write sharing, since
|
||||
# arbitrary buffer-exporting objects like bytearray() aren't guaranteed
|
||||
# to be immutable.
|
||||
ba = bytearray(1024)
|
||||
old_rc = sys.getrefcount(ba)
|
||||
memio = self.ioclass(ba)
|
||||
self.assertEqual(sys.getrefcount(ba), old_rc)
|
||||
|
||||
class CStringIOTest(PyStringIOTest):
|
||||
ioclass = io.StringIO
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue