Skip to content

Commit 5801967

Browse files
committed
docs/speed_python: Add many more details on memoryviews.
1 parent 47f9b10 commit 5801967

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

docs/reference/speed_python.rst

+20-7
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,31 @@ elements in contiguous memory locations. Once again to avoid memory allocation i
8585
code these should be pre-allocated and passed as arguments or as bound objects.
8686

8787
When passing slices of objects such as ``bytearray`` instances, Python creates
88-
a copy which involves allocation. This can be avoided using a ``memoryview``
89-
object:
88+
a copy which involves allocation of the size proportional to the size of slice.
89+
This can be alleviated using a ``memoryview`` object. ``memoryview`` itself
90+
is allocated on heap, but is a small, fixed-size object, regardless of the size
91+
of slice it points too.
9092

9193
.. code:: python
9294
93-
ba = bytearray(100)
94-
func(ba[3:10]) # a copy is passed
95-
mv = memoryview(ba)
96-
func(mv[3:10]) # a pointer to memory is passed
95+
ba = bytearray(10000) # big array
96+
func(ba[30:2000]) # a copy is passed, ~2K new allocation
97+
mv = memoryview(ba) # small object is allocated
98+
func(mv[30:2000]) # a pointer to memory is passed
9799
98100
A ``memoryview`` can only be applied to objects supporting the buffer protocol - this
99-
includes arrays but not lists.
101+
includes arrays but not lists. Small caveat is that while memoryview object is live,
102+
it also keeps alive the original buffer object. So, memoryviews isn't universal
103+
panacea. For instance, in the example above, if you are done with 10K buffer and
104+
just need those bytes 30:2000 from it, it may be better to make a slice, and let
105+
the 10K buffer go (be ready for garbage collection), instead of making a
106+
long-living memoryview and keeping 10K blocked for GC.
107+
108+
Nonetheless, ``memoryview`` is indispensable for advanced preallocated buffer
109+
management. ``.readinto()`` method discussed above puts data at the beginning
110+
of buffer and fills in entire buffer. What if you need to put data in the
111+
middle of existing buffer? Just create a memoryview into the needed section
112+
of buffer and pass it to ``.readinto()``.
100113

101114
Identifying the slowest section of code
102115
---------------------------------------

0 commit comments

Comments
 (0)