Does "__slots__" make sense in micropython

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Ephreal
Posts: 28
Joined: Tue Jan 15, 2019 1:41 pm

Does "__slots__" make sense in micropython

Post by Ephreal » Thu Nov 28, 2019 6:06 am

Hi

Is there a difference in using __slots__ vs __dict__ in MicroPython. I am not familiar with the inner workings.

Regards

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

Re: Does "__slots__" make sense in micropython

Post by pythoncoder » Thu Nov 28, 2019 8:02 am

You might like to see this discussion.
Peter Hinch
Index to my micropython libraries.

pidou46
Posts: 101
Joined: Sat May 28, 2016 7:01 pm

Re: Does "__slots__" make sense in micropython

Post by pidou46 » Thu Nov 28, 2019 10:45 am

Interesting,

Shouldn't it be mentioned in the docs (maybe in the Maximising Micropython Speed) ?

As I have I understand it could help save RAM. It not exactly speed optimisation, but it could help as I have frequently hit the RAM limit...

Am I wrong ?
nodemcu V2 (amica)
micropython firmware Daily build 05/31/2016

pidou46
Posts: 101
Joined: Sat May 28, 2016 7:01 pm

Re: Does "__slots__" make sense in micropython

Post by pidou46 » Thu Nov 28, 2019 10:56 am

nodemcu V2 (amica)
micropython firmware Daily build 05/31/2016

pidou46
Posts: 101
Joined: Sat May 28, 2016 7:01 pm

Re: Does "__slots__" make sense in micropython

Post by pidou46 » Thu Nov 28, 2019 2:29 pm

I have made some tests, and confirm it save some RAM :

Code: Select all

import gc
import micropython

class MyClass(object):
    #__slots__ = ['name', 'identifier']
    def __init__(self, name, identifier):
        self.name = name
        self.identifier = identifier
        
    def MyPrint(self):
        print('{}:{}'.format(self.name,self.identifier))

gc.collect()
micropython.mem_info()
toto=[]
for n in range(20):
    toto.append(MyClass('name','identifier'))
print("---------------------")
micropython.mem_info()


# ===========================================================
# Without __slot__
# 
# stack: 2096 out of 8192
# GC: total: 37952, used: 7792, free: 30160
#  No. of 1-blocks: 23, 2-blocks: 8, max blk sz: 264, max free sz: 1600
# ---------------------
# stack: 2096 out of 8192
# GC: total: 37952, used: 8592, free: 29360
#  No. of 1-blocks: 64, 2-blocks: 7, max blk sz: 264, max free sz: 1600
# 
# Used diff: 800
# 
# ===================================================================
# 
# With __slot__
# 
# stack: 2096 out of 8192
# GC: total: 37952, used: 7840, free: 30112
#  No. of 1-blocks: 25, 2-blocks: 7, max blk sz: 264, max free sz: 1627
# ---------------------
# stack: 2096 out of 8192
# GC: total: 37952, used: 8640, free: 29312
#  No. of 1-blocks: 66, 2-blocks: 6, max blk sz: 264, max free sz: 1627
# 
# Used diff: 352

nodemcu V2 (amica)
micropython firmware Daily build 05/31/2016

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

Re: Does "__slots__" make sense in micropython

Post by pythoncoder » Fri Nov 29, 2019 8:59 am

There is interesting discussion of __slots__ here.

A difference between MicroPython and CPython is that in CPython defining __slots__ prevents the creation of any other bound variables. Consider:

Code: Select all

class Foo:
    __slots__ = ()
foo = Foo()
foo.a = 42
Under CPython the last line throws an AttributeError whereas MicroPython accepts it. In CPython foo has no __dict__ attribute while MicroPython does.
Peter Hinch
Index to my micropython libraries.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Does "__slots__" make sense in micropython

Post by jimmo » Sun Dec 01, 2019 11:15 am

MicroPython doesn't support __slots__. The referenced PR (https://github.com/micropython/micropython/pull/3392) was never merged.
pidou46 wrote:
Thu Nov 28, 2019 2:29 pm
I have made some tests, and confirm it save some RAM :
Your tests show the difference as 800 bytes in both cases.

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

Re: Does "__slots__" make sense in micropython

Post by pythoncoder » Sun Dec 01, 2019 11:22 am

jimmo wrote:
Sun Dec 01, 2019 11:15 am
MicroPython doesn't support __slots__. The referenced PR (https://github.com/micropython/micropython/pull/3392) was never merged.
...
Do you happen to know why? It seems like a useful optimisation in terms of RAM usage and/or attribute access time. The CPython docs claim an access time improvement.
Peter Hinch
Index to my micropython libraries.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Does "__slots__" make sense in micropython

Post by jimmo » Sun Dec 01, 2019 11:56 am

pythoncoder wrote:
Sun Dec 01, 2019 11:22 am
Do you happen to know why? It seems like a useful optimisation in terms of RAM usage and/or attribute access time. The CPython docs claim an access time improvement.
Good question. It's not a huge amount of code. Might be worth revisiting now that MicroPython has the performance test suite?

The benefit for MicroPython compared to CPython is likely to be a lot smaller due to the way dicts are represented in MicroPython, but there is still an obvious RAM benefit. Performance... I don't have a good guess, but my intuition matches the comment from that PR that there wouldn't be much expected difference in MicroPython.

It's an interesting one -- as the PR also points out, the benefit also only kicks in asymptotically... I wonder how common is it to have enough instances of a given type that this actually starts to make a meaningful difference (but consider that the allocations are rounded up to a 16 byte GC block, which may work for or against this feature resulting in a significant difference...). I'm curious though, so will try and get some actual numbers sometime.

Post Reply