Skip to content

Commit

Permalink
docs/reference: Update constrained docs now that tuples can be const.
Browse files Browse the repository at this point in the history
Signed-off-by: Damien George <damien@micropython.org>
  • Loading branch information
dpgeorge committed Apr 14, 2022
1 parent 865b61d commit 9ab66b5
Showing 1 changed file with 16 additions and 11 deletions.
27 changes: 16 additions & 11 deletions docs/reference/constrained.rst
Expand Up @@ -126,8 +126,9 @@ that the objects remain in flash memory rather than being copied to RAM. The
Python built-in types.

When considering the implications of frozen bytecode, note that in Python
strings, floats, bytes, integers and complex numbers are immutable. Accordingly
these will be frozen into flash. Thus, in the line
strings, floats, bytes, integers, complex numbers and tuples are immutable.
Accordingly these will be frozen into flash (for tuples, only if all their
elements are immutable). Thus, in the line

.. code::
Expand All @@ -146,16 +147,16 @@ As in the string example, at runtime a reference to the arbitrarily large
integer is assigned to the variable ``bar``. That reference occupies a
single machine word.

It might be expected that tuples of integers could be employed for the purpose
of storing constant data with minimal RAM use. With the current compiler this
is ineffective (the code works, but RAM is not saved).
Tuples of constant objects are themselves constant. Such constant tuples are
optimised by the compiler so they do not need to be created at runtime each time
they are used. For example:

.. code::
foo = (1, 2, 3, 4, 5, 6, 100000)
foo = (1, 2, 3, 4, 5, 6, 100000, ("string", b"bytes", False, True))
At runtime the tuple will be located in RAM. This may be subject to future
improvement.
This entire tuple will exist as a single object (potentially in flash if the
code is frozen) and referenced each time it is needed.

**Needless object creation**

Expand Down Expand Up @@ -214,20 +215,24 @@ buffer; this is both faster and more efficient in terms of memory fragmentation.

**Bytes are smaller than ints**

On most platforms an integer consumes four bytes. Consider the two calls to the
On most platforms an integer consumes four bytes. Consider the three calls to the
function ``foo()``:

.. code::
def foo(bar):
for x in bar:
print(x)
foo([1, 2, 0xff])
foo((1, 2, 0xff))
foo(b'\1\2\xff')
In the first call a tuple of integers is created in RAM. The second efficiently
In the first call a `list` of integers is created in RAM each time the code is
executed. The second call creates a constant `tuple` object (a `tuple` containing
only constant objects) as part of the compilation phase, so it is only created
once and is more efficient than the `list`. The third call efficiently
creates a `bytes` object consuming the minimum amount of RAM. If the module
were frozen as bytecode, the `bytes` object would reside in flash.
were frozen as bytecode, both the `tuple` and `bytes` object would reside in flash.

**Strings Versus Bytes**

Expand Down

0 comments on commit 9ab66b5

Please sign in to comment.