summaryrefslogtreecommitdiffstatshomepage
path: root/docs/reference/speed_python.rst
diff options
context:
space:
mode:
authorAngus Gratton <angus@redyak.com.au>2025-02-04 12:20:38 +1100
committerDamien George <damien@micropython.org>2025-02-11 16:17:00 +1100
commit0a55f1f40c8a0a69f34f550d45138d9ba7a1d467 (patch)
treeeb1afdebdb07ff23e3c1ee6dbf6a60695087ea47 /docs/reference/speed_python.rst
parentbab099826e956bcc000b8a3c45b144c97d870fe2 (diff)
downloadmicropython-0a55f1f40c8a0a69f34f550d45138d9ba7a1d467.tar.gz
micropython-0a55f1f40c8a0a69f34f550d45138d9ba7a1d467.zip
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 <angus@redyak.com.au>
Diffstat (limited to 'docs/reference/speed_python.rst')
-rw-r--r--docs/reference/speed_python.rst33
1 files changed, 32 insertions, 1 deletions
diff --git a/docs/reference/speed_python.rst b/docs/reference/speed_python.rst
index 0c68dd60bd..a660432f6d 100644
--- a/docs/reference/speed_python.rst
+++ b/docs/reference/speed_python.rst
@@ -57,6 +57,8 @@ and used in various methods.
This is covered in further detail :ref:`Controlling garbage collection <controlling_gc>` below.
+.. _speed_buffers:
+
Buffers
~~~~~~~
@@ -69,6 +71,13 @@ example, objects which support stream interface (e.g., file or UART) provide ``r
method which allocates new buffer for read data, but also a ``readinto()`` method
to read data into an existing buffer.
+Some useful classes for creating reusable buffer objects:
+
+- :class:`bytearray`
+- :mod:`array` (:ref:`discussed below<speed_arrays>`)
+- :class:`io.StringIO` and :class:`io.BytesIO`
+- :class:`micropython.RingIO`
+
Floating point
~~~~~~~~~~~~~~
@@ -80,15 +89,20 @@ point to sections of the code where performance is not paramount. For example,
capture ADC readings as integers values to an array in one quick go, and only then
convert them to floating-point numbers for signal processing.
+.. _speed_arrays:
+
Arrays
~~~~~~
Consider the use of the various types of array classes as an alternative to lists.
-The `array` module supports various element types with 8-bit elements supported
+The :mod:`array` module supports various element types with 8-bit elements supported
by Python's built in `bytes` and `bytearray` classes. These data structures all store
elements in contiguous memory locations. Once again to avoid memory allocation in critical
code these should be pre-allocated and passed as arguments or as bound objects.
+Memoryviews
+~~~~~~~~~~~
+
When passing slices of objects such as `bytearray` instances, Python creates
a copy which involves allocation of the size proportional to the size of slice.
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
middle of existing buffer? Just create a memoryview into the needed section
of buffer and pass it to ``readinto()``.
+Strings vs Bytes
+~~~~~~~~~~~~~~~~
+
+MicroPython uses :ref:`string interning <qstr>` to save space when there are
+multiple identical strings. Each time a new string is allocated at runtime (for
+example, when two other strings are concatenated), MicroPython checks whether
+the new string can be interned to save RAM.
+
+If you have code which performs performance-critical string operations then
+consider using :class:`bytes` objects and literals (i.e. ``b"abc"``). This skips
+the interning check, and can be several times faster than performing the same
+operations with string objects.
+
+.. note:: The fastest performance will always be achieved by avoiding new object
+ creation entirely, for example with a reusable :ref:`buffer as described
+ above<speed_buffers>`.
+
Identifying the slowest section of code
---------------------------------------