ws2811/2812 Programs very slow
-
- Posts: 969
- Joined: Sat Feb 03, 2018 7:02 pm
Re: ws2811/2812 Programs very slow
You could try using a bytearray to store all the values. That's faster and saves RAM as the bytearray is not changed in size after creation.
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
Re: ws2811/2812 Programs very slow
kevinkk525 wrote:You could try using a bytearray to store all the values. That's faster and saves RAM as the bytearray is not changed in size after creation.
But tuples are immutable and he has tuple of ints which are completely immutable.
Why isn’t the same tuple being used for all array entries?
Sent from my iPhone using Tapatalk Pro
-
- Posts: 969
- Joined: Sat Feb 03, 2018 7:02 pm
Re: ws2811/2812 Programs very slow
True but he recreates those tuples in every iteration of the while loop. So instead of using a list of size n with each slot containing a tuple of size 3 (each slot being an integer), it would be better to use a bytearray size n*3 (also saving a lot of RAM as each "slot" would be a byte, not an integer). Would improve the performance as well.jickster wrote: ↑Tue Sep 25, 2018 5:21 pmkevinkk525 wrote:You could try using a bytearray to store all the values. That's faster and saves RAM as the bytearray is not changed in size after creation.
But tuples are immutable and he has tuple of ints which are completely immutable.
Why isn’t the same tuple being used for all array entries?
Sent from my iPhone using Tapatalk Pro
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
Re: ws2811/2812 Programs very slow
Where does he re-create the tuples?kevinkk525 wrote:True but he recreates those tuples in every iteration of the while loop. So instead of using a list of size n with each slot containing a tuple of size 3 (each slot being an integer), it would be better to use a bytearray size n*3 (also saving a lot of RAM as each "slot" would be a byte, not an integer). Would improve the performance as well.jickster wrote: ↑Tue Sep 25, 2018 5:21 pmkevinkk525 wrote:You could try using a bytearray to store all the values. That's faster and saves RAM as the bytearray is not changed in size after creation.
But tuples are immutable and he has tuple of ints which are completely immutable.
Why isn’t the same tuple being used for all array entries?
Sent from my iPhone using Tapatalk Pro
They’re created when they’re first used unless I don’t understand the immutability of tuples.
Sent from my iPhone using Tapatalk Pro
-
- Posts: 969
- Joined: Sat Feb 03, 2018 7:02 pm
Re: ws2811/2812 Programs very slow
He has an unconditional while loop and in there a for loop that recreates all the tuples in the array on each iteration of the while loop.jickster wrote: ↑Tue Sep 25, 2018 6:00 pmWhere does he re-create the tuples?kevinkk525 wrote:True but he recreates those tuples in every iteration of the while loop. So instead of using a list of size n with each slot containing a tuple of size 3 (each slot being an integer), it would be better to use a bytearray size n*3 (also saving a lot of RAM as each "slot" would be a byte, not an integer). Would improve the performance as well.
They’re created when they’re first used unless I don’t understand the immutability of tuples.
Sent from my iPhone using Tapatalk Pro
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
Re: ws2811/2812 Programs very slow
I see the loop but tuples are immutable like ints.kevinkk525 wrote:He has an unconditional while loop and in there a for loop that recreates all the tuples in the array on each iteration of the while loop.jickster wrote: ↑Tue Sep 25, 2018 6:00 pmWhere does he re-create the tuples?kevinkk525 wrote: True but he recreates those tuples in every iteration of the while loop. So instead of using a list of size n with each slot containing a tuple of size 3 (each slot being an integer), it would be better to use a bytearray size n*3 (also saving a lot of RAM as each "slot" would be a byte, not an integer). Would improve the performance as well.
They’re created when they’re first used unless I don’t understand the immutability of tuples.
Sent from my iPhone using Tapatalk Pro
If I say
a = 555555555555555555555555
b = 555555555555555555555555
Shouldn’t “b” point to the same int object in memory?
Same principle
c = (255,0,0)
d = (255,0,0)
Maybe my understanding is wrong. Idk. Send me a link to read if I’m wrong.
Sent from my iPhone using Tapatalk Pro
-
- Posts: 969
- Joined: Sat Feb 03, 2018 7:02 pm
Re: ws2811/2812 Programs very slow
Hmm I don't have anything to read about that.jickster wrote: ↑Tue Sep 25, 2018 6:06 pmI see the loop but tuples are immutable like ints.kevinkk525 wrote:He has an unconditional while loop and in there a for loop that recreates all the tuples in the array on each iteration of the while loop.
If I say
a = 555555555555555555555555
b = 555555555555555555555555
Shouldn’t “b” point to the same int object in memory?
Same principle
c = (255,0,0)
d = (255,0,0)
Maybe my understanding is wrong. Idk. Send me a link to read if I’m wrong.
Sent from my iPhone using Tapatalk Pro
But a definitely has not the same memory as b. Easy to test because if you add 1 to a, b would be 1 bigger as well, which of course does not happen (if micropython separetes the memory only when one of the objects get modified then idk about that).
As for tuples they are immutable once created but I don't know if all tuples with equal values have the same memory.
But even then he stores first tuples (0,0,0) in every slot in the list and then iterates over the list changing some slots to (255,0,0).
Maybe the performance problem and the neccessity for gc.collect() comes from the recreation of tuples.
But I did not intend to turn a question about basic micropython stuff into a discussion on "developer level", having to look at the internals of micropython (because I have no knowledge of that anyways). I just thought he'd be better off using bytearrays which could solve his RAM and performance problems.
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
You could try this
@ARTaylor Firstly I'm surprised that your code is slowing down so very much. Normally garbage collection occurs in a very few milliseconds.
However I can see ways to improve things. Firstly, as others have suggested, create a bytearray and re-use it. This avoids allocation. Secondly I think your code can be made quicker by not zeroing every LED on every pass. Can you not do something like this?
Apologies if I've missed something here - I haven't got the hardware to hand to test this.
However I can see ways to improve things. Firstly, as others have suggested, create a bytearray and re-use it. This avoids allocation. Secondly I think your code can be made quicker by not zeroing every LED on every pass. Can you not do something like this?
Code: Select all
from time import sleep
pixelcount = 50
np = NeoPixel(Pin(19), pixelcount)
buf = bytearray(3)
while True: # Green chaser
for i in range(pixelcount):
buf[0] = 255
np[i] = buf
np.write()
buf[0] = 0 # Blank the LED you've just written
np[i] = buf # this will take effect on the next pass
sleep(0.01)
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: ws2811/2812 Programs very slow
Wrap your while True loop in a function and reply with the results on memory usage.
Stackoverflow says tuples allocated inside a function are cached.
Sent from my iPhone using Tapatalk Pro
Stackoverflow says tuples allocated inside a function are cached.
Sent from my iPhone using Tapatalk Pro
Re: ws2811/2812 Programs very slow
It's far more than 50.ARTaylor wrote: ↑Tue Sep 25, 2018 4:41 pmWriting the tuple is the problem:
for example, commenting that out fixes the issue. I guess the value for every LED is being stored, and 50+ is excessiveCode: Select all
np = (n,n,n)
The statement (255, 0, 0) is creating a new tuple every single time. I thought there'd be caching but guess not.
To fix it, all you have to do is create dummy vars to hold (255, 0, 0) and (0, 0, 0) initially and then assign it to np as needed.
Code: Select all
from machine import Pin
from neopixel import NeoPixel
from time import sleep
import gc
pixelcount = 50
np = NeoPixel(Pin(19), pixelcount)
led_on = (255, 0, 0)
led_off = (0, 0, 0)
for n in range(pixelcount):
np[n] = led_off
while True:
# Green
# Reset all LEDs
for i in range(pixelcount):
np[i] = led_on
np.write()
np[i] = led_off
sleep(0.01)
If this is your entire program, you don't EVER have to do gc.collect().