Games performance of using lists vs arrays

andymc

Well-Known Member
Licensed User
Longtime User
I use lists for my objects on my games, but this mean during a game loop, I use something similar to the following:

B4X:
Dim x As Int = 0
        Do While x < bullets.Size
            bulletAlive = True
            Dim mybullet As typBullet
            'CHANGED
            mybullet.Initialize
            mybullet = bullets.Get(x)
            mybullet.y = mybullet.y + mybullet.my
            mybullet.x = mybullet.x + mybullet.mx
......update more bullets details......
x = x + 1
loop

Is this efficient? It seems wrong to dim new objects and initialize them during a render loop. With my new game I may be doing this for hundreds of objects per frame.

Also, does anyone know if there is a performance hit in using drawtex2 to resize a texture rather than just using a texture with the correct normal size and use drawtex ? I have been stretching backgrounds.
 

andymc

Well-Known Member
Licensed User
Longtime User
I found this comment on a different site and am now worried this is what I'm doing

Tip number 3: Avoid to create new instances of any objects
It is related to tip 2. You should never create an instance of a new object inside the render call, because it will create a new instance every draw call. As I said before these are 60 calls / second and java will always allocate new memory for the new instance. So avoid stuff like that:


pubic void draw(SpriteBatch batch) {
Effect healEffect = new Effect(); // this one should not be instantiated inside the draw call
healEffect.draw();
}
 

ilan

Expert
Licensed User
Longtime User
No its not wrong. I do it in all my games and i have very good results even with lots of loops BUT i never use do...while loops.

There is no need for that just use for ... next loop instaed.
 

andymc

Well-Known Member
Licensed User
Longtime User
Thanks Ilan,

when I use for...next loop I always end up getting errors when trying to remove items during the loop.

I'm trying to be better at performance, I've made some changes to my Mars Defender game which has improved performance a little. It mostly comes form drawing too many stretched textures.
 

ilan

Expert
Licensed User
Longtime User
Thanks Ilan,

when I use for...next loop I always end up getting errors when trying to remove items during the loop.

I'm trying to be better at performance, I've made some changes to my Mars Defender game which has improved performance a little. It mostly comes form drawing too many stretched textures.

yes i saw it in your old cloney bird example

how i solve it is very simple

This is the Loop. Its goes through all items in the list and if an item as the value that should tell me (the developer) to remove it from the list like .hit = true then i add it to another list and then i sort the list and remove all items secure without any crashes or blinks!!

toremove is a global list!!

B4X:
Sub runExplosions
    Dim index As Int = 0
    For Each explosion As SKSpriteNode In ExplosionList
        If explosion.HasActions = False Then
            explosion.RemoveFromParent
            toremove.Add(index)
        End If
        index = index + 1
    Next
    toRemoveSub(ExplosionList)
End Sub

B4X:
Sub toRemoveSub(l As List)
    toremove.Sort(False)
    For i = 0 To toremove.Size-1
        l.RemoveAt(toremove.Get(i))
    Next
    toremove.Clear
End Sub
 

wonder

Expert
Licensed User
Longtime User
My KZ engine utilizes Lists and Maps without any performance issues. :)

@ilan, you can remove objects on the fly without creating waiting lists... ;) ;) ;)
B4X:
Sub runExplosions
    For index = (ExplosionList.Size - 1) To 0 Step -1
        Dim explosion = ExplosionList.Get(index) As SKSpriteNode
        If explosion.HasActions Then Continue
        explosion.RemoveFromParent
        ExplosionList.RemoveAt(index)      
    Next
End Sub
The trick resides in traversing the list backwards! ;)

@wonder is now patiently awaiting for the "HOLY SHIT!!! IT WORKS!!!" post...
 
Last edited:

ilan

Expert
Licensed User
Longtime User
My KZ engine utilizes Lists and Maps without any performance issues. :)

@ilan, you can remove objects on the fly without creating waiting lists... ;) ;) ;)
B4X:
Sub runExplosions
    For index = (ExplosionList.Size - 1) To 0 Step -1
        Dim explosion = ExplosionList.Get(index) As SKSpriteNode
        If explosion.HasActions Then Continue
        explosion.RemoveFromParent
        ExplosionList.RemoveAt(index)    
    Next
End Sub
The trick resides in traversing the list backwards! ;)

@wonder is now patiently awaiting for the "HOLY SHIT!!! IT WORKS!!!" post...

Yes i know that u can go through a loop backwarts. This is also a solution but i was told that the "for each" is faster then the "for next" and most of the time the "toremove" list will hold a very low number of items and like this u can benefit from the "for each" loop that goes through a big amount of items.

If i remember the thread was made by u ;)
 

ilan

Expert
Licensed User
Longtime User
I've read that lgarrays are faster than using lists. I've tried it, it's very easy to do but I can't really tell if it's made a difference

i am also using lgarrays in my libgdx games. i am not sure they are faster but i think its the better way to do.
 

andymc

Well-Known Member
Licensed User
Longtime User
the only other performance issue I worry about is bitmap fonts, I think scaling fonts during the render batch may cause issues, I'm going to experiment by using fontgenerator to generate different sized font objects, then use those instead of scaling during the render loop.
I'm also interested whether drawtex is more efficient than drawtex2 I use drawtex2 to scale up textures to fill the screen when the source texture file is much smaller.
 

ilan

Expert
Licensed User
Longtime User
the only other performance issue I worry about is bitmap fonts, I think scaling fonts during the render batch may cause issues, I'm going to experiment by using fontgenerator to generate different sized font objects, then use those instead of scaling during the render loop.
I'm also interested whether drawtex is more efficient than drawtex2 I use drawtex2 to scale up textures to fill the screen when the source texture file is much smaller.

i had performance issues with your latest game when i was in a very high wave. it drops to maybe about 20fps instead of 60fps. But I don't think it has something to do with bitmap fonts or usings lists instead of lgarrays and for sure not drawtex2!

i think you are not removing all items and your lists grow very high and your loops become to big.

try to switch all "do...while" loop to "for...next" (or "for each") and make sure you remove all bullets that are outside the screen! or any object that are no more needed.
 

wonder

Expert
Licensed User
Longtime User
Here's the generated Java code, side-by-side with its B4J counterpart.

upload_2017-10-31_20-12-24.png


It seems that the While loop is the cleanest when having an index...
Oh well, refactoring hundreds of lines of code, here we go...
 
Top