Any tips for optimisation? (aka I dare you to make this faster!)

kcorey

Member
Licensed User
Longtime User
So, I think I've optimised this fairly well. This is my inner loop of a particle function, and it can handle a few hundred particles satisfactorily...but the geek in me thinks there must be ways to speed it up even more.

It is of course using the fantastic OpenGL example code provided by Jim Brown, which is sitting on top of Andrew Graham's OpenGL and Reflection libraries. Just...wow. Thanks for releasing both of your sets of code. If I ever run into either of you, a beer is on me!

Any pros out there know how this could be sped up? I'm currently using 2.02 (no real reason...I just installed the stable version rather than the beta).

The areas I'm suspicious of are the admin of the loop, using the particlelist.Get(i) and particlelist.RemoveAt(i) functions, and using p as a reference to a particular item in the list.

Also, I'm measuring the life of each particle, when in fact I could just measure the life of each set of 32 particles once, and skip the check for the rest. Likewise, instead of removing 32 particles with identical lives at the same time, is there a way with a list to say "just drop the first 32"?

Were I using Java or Javascript, I'd use a foreach kind of function to avoid indexing and loop overheads altogether. Would jumping to the 2.20 beta get this for me? Is that a faster way to do things in B4A?

Is there a better way to do the bit shifting? Does Bit.SignedShiftRight really speed things up?

Thanks for any tips!

-Ken

B4X:
sub Process_Globals
        Dim particlelist as list
   Dim robot1 As GLImage        
end sub

Sub glsv_Draw(gl As GL1)
   Dim p As Particle
   Dim i,lim As Int
   
   GLDisplay.Cls(gl)

   ' i is the particle we're working on.
   i=0
   lim = particlelist.Size
   
   Do While i < lim
      p = particlelist.Get(i)
      
      ' age particle, draw if still alive.
      p.life=p.life-p.dlife
      If p.life<=0 Then
         particlelist.RemoveAt(i)
         lim = lim-1
      Else
         ' dx and dy are signed fixed point, -63 1/128 to 63 1/128
         ' this gets rid of the fractional part
         p.x = p.x + Bit.ShiftRight(p.dx,7)         
         p.y = p.y + Bit.ShiftRight(p.dy,7)
         ' add a fractional 48/128 to simulate gravity
         p.dy = p.dy+48

         robot1.SetColor(p.red,p.green,p.blue)
         robot1.SetSize(p.size,p.size)
         robot1.SetAlpha(p.life*4)
         robot1.Drawat(p.x,p.y,gl)            
         
         i=i+1
      End If
   Loop   
End Sub
 

Informatix

Expert
Licensed User
Longtime User
AFAIK, a For-Each loop in Java is not faster than other methods of writing a loop. It's just more convenient in some cases.

When you remove an item in a list, it loses its reference in your application and the garbage collector can come into play (the GC is a process that tries to free unused memory). Fortunately, it doesn't come up every time we change something in memory. When it does its cleaning job, it usually slows down your program noticeably, so if you want maximum speed, never do objects allocations or removals in the loop.

EDIT: I just saw that Erel said the same thing. Sorry.
 
Upvote 0
Top