Why are tiledbackgrounds more efficient than sprites? Sounds like its best to use them for anything static.
It's the same rules as Construct Classic. Grids of sprites are incredibly inefficient at two things: rendering, and collisions.
For rendering, graphics cards are very good at repetitions and can draw a tiled background of any size in about the same time it takes to draw a single sprite. However, if you have a grid of sprites, they're all drawn separately (because it isn't aware that their positions and angles align to make a grid).
So if you have a 20x20 grid of sprites on-screen, it draws 400 times slower than if you had a tiled background the same size. It could have rendered an entire tiled background by the time it's finished rendering the first sprite in the grid of 400. That's a pretty massive performance hit. So, always use tiled backgrounds wherever you can!
Secondly, for collisions there is a similar case. To test if an object overlaps another one, it generally has to test if it overlaps any of its instances. A tiled background counts as one instance, and again a 20x20 grid of sprites counts as 400 instances. So instead of making 1 collision check, it makes 400. Again, 400 times slower.
Imagine if your grid is bigger than 20x20! Even worse! Once more for luck: always use tiled backgrounds wherever you possibly can!
However, it appears to be making a sprite for each and every value in the array.
ceil(random(0, 1)) is almost always 1, because ceil(0.0000001) is still 1. It will only ever be 0 when random(0, 1) returns exactly 0, which is basically never, because there are a lot of possible values between 0 and 1!
You should also know that 'for each element' also triggers once for every element in a 3D array, including repeating the event for each element down the Z axis. If you have a 128x128x32 array, For Each Element is repeating the event 32 times for each 2D cell, which you probably don't want...