Skip to content

Commit 0a55f1f

Browse files
projectgusdpgeorge
authored andcommitted
docs/reference: Add strings vs bytes to speed optimisation tips.
Also add some additional context links, suggestions for alternative classes, etc. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
1 parent bab0998 commit 0a55f1f

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

docs/library/array.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ Classes
1919
array are given by *iterable*. If it is not provided, an empty
2020
array is created.
2121

22+
In addition to the methods below, array objects also implement the buffer
23+
protocol. This means the contents of the entire array can be accessed as raw
24+
bytes via a `memoryview` or other interfaces which use this protocol.
25+
2226
.. method:: append(val)
2327

2428
Append new element *val* to the end of array, growing it.

docs/library/builtins.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Functions and types
1919

2020
.. class:: bytearray()
2121

22+
|see_cpython| `python:bytearray`.
23+
2224
.. class:: bytes()
2325

2426
|see_cpython| `python:bytes`.
@@ -104,6 +106,8 @@ Functions and types
104106

105107
.. class:: memoryview()
106108

109+
|see_cpython| `python:memoryview`.
110+
107111
.. function:: min()
108112

109113
.. function:: next()

docs/reference/speed_python.rst

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ and used in various methods.
5757

5858
This is covered in further detail :ref:`Controlling garbage collection <controlling_gc>` below.
5959

60+
.. _speed_buffers:
61+
6062
Buffers
6163
~~~~~~~
6264

@@ -69,6 +71,13 @@ example, objects which support stream interface (e.g., file or UART) provide ``r
6971
method which allocates new buffer for read data, but also a ``readinto()`` method
7072
to read data into an existing buffer.
7173

74+
Some useful classes for creating reusable buffer objects:
75+
76+
- :class:`bytearray`
77+
- :mod:`array` (:ref:`discussed below<speed_arrays>`)
78+
- :class:`io.StringIO` and :class:`io.BytesIO`
79+
- :class:`micropython.RingIO`
80+
7281
Floating point
7382
~~~~~~~~~~~~~~
7483

@@ -80,15 +89,20 @@ point to sections of the code where performance is not paramount. For example,
8089
capture ADC readings as integers values to an array in one quick go, and only then
8190
convert them to floating-point numbers for signal processing.
8291

92+
.. _speed_arrays:
93+
8394
Arrays
8495
~~~~~~
8596

8697
Consider the use of the various types of array classes as an alternative to lists.
87-
The `array` module supports various element types with 8-bit elements supported
98+
The :mod:`array` module supports various element types with 8-bit elements supported
8899
by Python's built in `bytes` and `bytearray` classes. These data structures all store
89100
elements in contiguous memory locations. Once again to avoid memory allocation in critical
90101
code these should be pre-allocated and passed as arguments or as bound objects.
91102

103+
Memoryviews
104+
~~~~~~~~~~~
105+
92106
When passing slices of objects such as `bytearray` instances, Python creates
93107
a copy which involves allocation of the size proportional to the size of slice.
94108
This can be alleviated using a `memoryview` object. The `memoryview` itself
@@ -118,6 +132,23 @@ of buffer and fills in entire buffer. What if you need to put data in the
118132
middle of existing buffer? Just create a memoryview into the needed section
119133
of buffer and pass it to ``readinto()``.
120134

135+
Strings vs Bytes
136+
~~~~~~~~~~~~~~~~
137+
138+
MicroPython uses :ref:`string interning <qstr>` to save space when there are
139+
multiple identical strings. Each time a new string is allocated at runtime (for
140+
example, when two other strings are concatenated), MicroPython checks whether
141+
the new string can be interned to save RAM.
142+
143+
If you have code which performs performance-critical string operations then
144+
consider using :class:`bytes` objects and literals (i.e. ``b"abc"``). This skips
145+
the interning check, and can be several times faster than performing the same
146+
operations with string objects.
147+
148+
.. note:: The fastest performance will always be achieved by avoiding new object
149+
creation entirely, for example with a reusable :ref:`buffer as described
150+
above<speed_buffers>`.
151+
121152
Identifying the slowest section of code
122153
---------------------------------------
123154

0 commit comments

Comments
 (0)