Distance Checking For DarkBasic Classic

Started by kevin, January 29, 2009, 12:19:41 AM

Previous topic - Next topic

kevin

 Distance Checking For DarkBasic Classic

   This test, simply demo's a few ways to attack the optimization of the CheckDistance function in DarkBasic Classic.  This can important in  when performing nested collision checks (checking a list of objects against themselves, or other lists) due to the high frequency of calls to the Check Distance functions in those cases.  This can be very important as DarkBasic Classic has no built function to calc the distance.





Sync on

   tests=5000

   Range=100
   RangeSquared=Range*Range

   FireX=100
   FireY=100
   EnemyX=200
   EnemyY=200


Do
  Cls

   inc frames
     t=timer()

    For lp=0 to tests

     result=CheckDistance(FireX,FireY,EnemyX,EnemyY,Range)
    next lp
      tt1#=tt1#+(Timer()-t)

    text 100,100,"Square Root:"+str$(tt1#/frames)

     t=timer()
     For lp=0 to tests
        result=CheckDistance2(FireX,FireY,EnemyX,EnemyY,Range)
     next lp

    tt2#=tt2#+(Timer()-t)

  text 100,130,"Square Root Refined:"+str$(tt2#/frames)

    t=timer()
     For lp=0 to tests
        result=CheckDistance3(FireX,FireY,EnemyX,EnemyY,Range)
     next lp

    tt3#=tt3#+(Timer()-t)

  text 100,160,"Squared:"+str$(tt3#/frames)
 

   t=timer()
     For lp=0 to tests
        result=CheckDistance4(FireX,FireY,EnemyX,EnemyY,RangeSquared)
     next lp

    tt4#=tt4#+(Timer()-t)

  text 100,190,"PreSquared:"+str$(tt4#/frames)
 


`  This Loop removes the function and performs the calc inside the loop
`  So basically we're inlining the function manually.
  t=timer()
     For lp=0 to tests

DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
  result=(DiffX*DiffX + DiffY*DiffY)  < RangeSquared
     
     next lp

    tt5#=tt5#+(Timer()-t)

  text 100,220,"Inline:"+str$(tt5#/frames)
 






  Sync

loop


Function CheckDistance(FireX,FireY,EnemyX,EnemyY,Range)
  DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
  Distance = abs( sqrt(DiffX*DiffX + DiffY*DiffY) )
  if Distance < Range then RetVal = 1 else RetVal = 0
EndFunction RetVal



Function CheckDistance2(FireX,FireY,EnemyX,EnemyY,Range)
  DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
   exitfunction  sqrt(DiffX*DiffX + DiffY*DiffY)  < Range
endFunction RetVal



Function CheckDistance3(FireX,FireY,EnemyX,EnemyY,Range)
  DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
   exitfunction  (DiffX*DiffX + DiffY*DiffY)  < (Range*Range)
endFunction RetVal



Function CheckDistance4(FireX,FireY,EnemyX,EnemyY,RangeSquared)
  DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
   exitfunction  (DiffX*DiffX + DiffY*DiffY)  < RangeSquared
endFunction RetVal






PlayBasic Version Of this test

    The PB version has one extra test added, this one uses the built in Distance function.  While the built in function is much quicker than user defined subs, Interestingly it's a fraction slower than the inline version in PlayBasicV1.64j (VM1). 




   tests=5000

   ThisRange=100
   RangeSquared=ThisRange*ThisRange

   FireX=100
   FireY=100
   EnemyX=200
   EnemyY=200




Do
  Cls 0

   inc frames
     t=timer()

Ypos=100
RowHeight=35

    For lp=0 to tests
     result=CheckDistance(FireX,FireY,EnemyX,EnemyY,ThisRange)
    next lp
      tt1#=tt1#+(Timer()-t)

    text 100,Ypos,"Square Root:"+str$(tt1#/frames)
   Ypos=Ypos+Rowheight

     t=timer()
     For lp=0 to tests
        result=CheckDistance2(FireX,FireY,EnemyX,EnemyY,ThisRange)
     next lp

    tt2#=tt2#+(Timer()-t)

  text 100,Ypos,"Square Root Refined:"+str$(tt2#/frames)
   Ypos=Ypos+Rowheight

    t=timer()
     For lp=0 to tests
        result=CheckDistance3(FireX,FireY,EnemyX,EnemyY,ThisRange)
     next lp

    tt3#=tt3#+(Timer()-t)

  text 100,Ypos,"Squared:"+str$(tt3#/frames)
   Ypos=Ypos+Rowheight
 

   t=timer()
     For lp=0 to tests
        result=CheckDistance4(FireX,FireY,EnemyX,EnemyY,RangeSquared)
     next lp

    tt4#=tt4#+(Timer()-t)

  text 100,Ypos,"PreSquared:"+str$(tt4#/frames)
   Ypos=Ypos+Rowheight
 


 



`  This Loop removes the function and performs the calc inside the loop
`  So basically we're inlining the function manually.
  t=timer()
     For lp=0 to tests
  result=GetDistance2d(firex,firey,EnemyX,EnemyY)
     next lp
    tt6#=tt6#+(Timer()-t)
   text 100,Ypos,"Built In Function:"+str$(tt6#/frames)
 
   Ypos=Ypos+Rowheight


`  This Loop removes the function and performs the calc inside the loop
`  So basically we're inlining the function manually.
  t=timer()
     For lp=0 to tests
DiffX = FireX-EnemyX
DiffY = FireY-EnemyY
result=(DiffX*DiffX + DiffY*DiffY)  < RangeSquared
     next lp
    tt5#=tt5#+(Timer()-t)

  text 100,Ypos,"Inline:"+str$(tt5#/frames)

   Ypos=Ypos+Rowheight


  Sync

loop


Psub CheckDistance(FireX,FireY,EnemyX,EnemyY,ThisRange)
  DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
  Distance = abs( sqrt(DiffX*DiffX + DiffY*DiffY) )
  if Distance < ThisRange
  RetVal = 1
   else
    RetVal = 0
endif
EndPsub RetVal



Psub CheckDistance2(FireX,FireY,EnemyX,EnemyY,ThisRange)
  DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
   RetVal= sqrt(DiffX*DiffX + DiffY*DiffY)  < ThisRange
endPsub RetVal



Psub CheckDistance3(FireX,FireY,EnemyX,EnemyY,ThisRange)
  DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
   RetVal=(DiffX*DiffX + DiffY*DiffY)  < (ThisRange*ThisRange)
endPsub RetVal



Psub CheckDistance4(FireX,FireY,EnemyX,EnemyY,RangeSquared)
  DiffX = FireX-EnemyX
  DiffY = FireY-EnemyY
   RetVal=  (DiffX*DiffX + DiffY*DiffY)  < RangeSquared
endPsub RetVal