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>
This commit is contained in:
committed by
Damien George
parent
bab099826e
commit
0a55f1f40c
@@ -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
|
||||
---------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user