Markus Gritsch wrote:pfalcon wrote:If it's clear, why do you use it, and not rewrite that program in non-wasteful way?
The wasteful thing is, that one has to create the pattern for the LEDs all as one large chunk so that it can be handled as one SPI transfer, to get the timing right.
Ok, but that's not what I'm trying to hint. Let's look at your code - you start with efficient, inplace data structure bytearray, but from it, you go to much less efficient list, and don't even use inplace modification for it, instead creating new one each time. And what you do exactly is: pass values one by one thru external function (slow), collect such values one by one into list (slow), join them back (slow and wasteful - you split stuff just to join it back as the next step).
Surely, that piece of code is expressive, but the only way to get it efficient is to pass thru giant set of optimizations (as a bit of trivia, latest versions of Clang/LLVM easily compile to binaries of ~1Gb size - that's how much code needed to optimize (other) code to be small and fast). Surely, MicroPython can't do that (for comparison, uPy already does more optimization on bytecode than CPython does). So, if you want to write expressive code, write expressive code. And if you want efficient code, write efficient code.
I hope it's obvious what needs to be done with your code - 1) pre-allocate bytearrays for everything you need outside the loop; 2) byte2bits() should take input and output arrays, and convert one to another inplace, in one big boring loop, just like you'd do it in C. And I hope you don't challenge C's way - it does it that way, because it's the most efficient.