Memory: Is "from X import Y" better than "import X"?

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
NTL2009
Posts: 20
Joined: Wed Oct 26, 2016 10:07 pm

Memory: Is "from X import Y" better than "import X"?

Post by NTL2009 » Tue Jun 13, 2017 4:41 pm

I'm occasionally getting errors when my ESP boots a new version of main.py, like:
MemoryError: memory allocation failed, allocating 557 bytes
Which I think I understand to be running out of memory as the ESP tries to compile the main.py file.

I manage to find ways to reduce the code size or variable allocations, but I'm wondering if other things will help. Specifically, if I'm only using a few commands from an imported module, I assume the "from X import Y" approach means I'm only importing those particular sections, saving memory? Is that right?

My specific example:
from utime import time,sleep,localtime;from machine import reset,RTC,Pin

I also import usocket rather than socket. I understand the 'u' versions may be more limited, but if they do what I need I'm good?

The "import from" also makes the code a bit smaller, as I code
x=time() rather than x=utime.time()
and I have a lot of those commands. Byte-code wise, probably no difference, but I'm not compiling anything, just loading a text "main.py" file.

Is there anyway to get the Memory Allocation when it doesn't fail (so I can be proactive, and see when I get close)?

Any clarification is greatly appreciated. -NTL2009

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Memory: Is "from X import Y" better than "import X"?

Post by Roberthh » Tue Jun 13, 2017 6:50 pm

These are a lot of questions, and I try to answer a few.
- It is generally considered good style to keep main.py short and put your payload of code into separate scripts, which are imported by main. When importing, the ESP may run out of memory in the compile phase. Splitting your code in smaller scripts reduces that risk a little bit. To avoid out-of-memorry situations in the compile phase, you can also use mpy-cross to compile externally and use pre-compiled scripts. Finally, you may embed python code into the flash as frozen bytecode.
- For modules embedded in flash the difference between "import xyz" and form xyz import abc" is minor, since only the name tables will be established in RAM, but the code stays in flash. Whther it makes a difference for modules loaded into RAM, I did not test.
- On ESP, there is no differemcve between usocket and socket besides the name. The set of methods is the same.
- For the analysis of memory allocation, you can use gc.mem_free(), gc.mem_alloc(), micropython.mem_info(), esp.info(), .. Use gc.collect() to set the device to a defined state when comparing things.
And not to forget: read the docs. They contain a lot of useful information and are made to be read.

NTL2009
Posts: 20
Joined: Wed Oct 26, 2016 10:07 pm

Re: Memory: Is "from X import Y" better than "import X"?

Post by NTL2009 » Wed Jun 14, 2017 2:04 am

Thanks. Yes, I should probably look into compiling with mpy-cross, I've read about it here, just haven't made the jump to learning another tool yet.

I familiar with some of the memory functions you mentioned, but I'll need to look again, I was thinking they only provide info after the compiling is done (and the compile step is where I seem to be running into troubles). My program reports ~ 20976 or thereabouts gc.mem_free(), that's one of the last pieces of data I pass to my server when I upload data once an hour. I do a collect within my main loop.

I do look through the documentation, but I'm just not conversant enough in a lot of these terms to absorb what it's telling me. Though helpful people on this forum, like yourself, help to translate it for me.

I also need to check my forum settings, I didn't get an email alerting me to a post in this thread, I just saw your response now on a refresh.

-NTL2009

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Memory: Is "from X import Y" better than "import X"?

Post by pythoncoder » Wed Jun 14, 2017 8:00 am

The memory error often results from heap fragmentation. If your code attempts to allocate an object requiring N bytes of contiguous RAM, a failure will occur if the largest contiguous block is too small. The solution is periodically to perform garbage collection. If you're importing Python source modules, try issuing gc.collect() after each import. If the failure occurs at runtime, arrange for your code to do a periodic collection.
Peter Hinch
Index to my micropython libraries.

Post Reply