PlayBASIC V1.64k Beta 7 - Stacks opt's = Better recursion speed. Been working on the stack controls the past couple of days, made a few improvements in previous beta's, which turned out to be hindrances also, but ya get that ! - The stack is really a hidden bottle neck in how various parts of PB runtime (VM1) perform. So improving the stack functionality can make the overall runtime performance that little bit snappier. Which means your programs can run faster.
The current changes have been mostly relating to how a change of scope occurs (function calling). The old version is very polite and includes a wealth of error trapping and type matching that isn't always needed (however, some times it is!) - So, what I've been doing is restructuring the call function stack usage , to remove as much of nanny code as possible.
It's taken a lot longer than i'd originally expected to get working, but finally the scope change caller is yielding almost universally better results. For a simple function calls (small functions) it's only slightly faster though. In fact, BEta 7 is slower than previous betas in this regard. However, previous beta's relies upon a few too many assumptions, in others words, they don't actually work correctly
Beta 7 is quicker than previous PBV1.64j retail editions and thats what matters, but only marginally (by a couple of %), where it starts to shine is in calling larger scopes (big fat functions with lots of locals) and in particular recursive function calls.
In the example bellow we have a parent/child structure that's designed to use recursion.
V1.64k Beta 7 runs this example approximately %30 faster then V1.64J Retail. Which is nothing to sneeze at..
Constant MaxChildren=255
Type tObjectParent
x#,y#
TranslatedX#,TranslatedY#
Angle#
ScaleX#
ScaleY#
Colour
Size
Parent
ChildCount ; max kids
Children(MaxChildren) // This obejct can have a 255 children attached to it
EndType
Type tObjectChild as TobjectParent
Endtype
// This array holds the entire data structure of parents and their children
Dim Ball(0) as tobjectParent
TestParent=CreateParent(100,200,45)
// Append Child to the parent
Child2=AddChildToParent(testParent,100,100,00)
// append a bunch of kids to the Child
Kids=50
Dim Children(Kids)
for lp=1 to Kids
angle#=(360.0/Kids)*lp
x#=cos(angle#)*150
y#=sin(angle#)*150
Children(lp)=AddChildToParent(Child2,x#,y#,0)
next
; setfps 100
Do
cls $204080
TurnObject(TestParent,2.25)
PositionObject(TestParent,mousex(),mousey())
sangle#=wrapangle(sangle#,1)
s#=2+cos(sangle#)*1
s#=1
ScaleObject(Child2,s#,s#)
// loop through and process all the parent objects
lockbuffer
t=timer()
for lp=1 to GetArrayElements(Ball(),1)
if TypeOf(Ball(lp))=tObjectParent
// process a parent object
ParentX#=Ball(lp).x#
ParentY#=Ball(lp).y#
Angle# =Ball(lp).angle#
ScaleX# =Ball(lp).scalex#
ScaleY# =Ball(lp).scaley#
circlec parentx#,parenty#,Ball(lp).size,true,Ball(lp).colour
// DRaw it's kids
DrawChildren(lp,ParentX#,ParentY#,angle#,scaleX#,scaleY#)
endif
next
tt#=tt#+(Timer()-t)
unlockbuffer
inc frames
print tt#/frames
Sync
loop
Function CreateParent(X#,y#,angle#)
Index=GetFreeCell(Ball())
Ball(index).x#=x#
Ball(index).y#=y#
Ball(index).ScaleX# =1
Ball(index).ScaleY# =1
Ball(index).Angle#=angle#
Ball(index).size =20
Ball(index).colour =$ff0000
EndFunction Index
Function TurnObject(Index,AngleStep#)
Ball(index).angle#=wrapangle(Ball(index).angle#,AngleStep#)
EndFunction Index
Function ScaleObject(Index,ScaleX#,scaley#)
Ball(index).ScaleX# =ScaleX#
Ball(Index).ScaleY# =ScaleX#
EndFunction
Function PositionObject(Index,X#,y#)
Ball(index).x#=x#
Ball(index).y#=y#
EndFunction Index
Function AddChildToParent(ParentIndex,X#,y#,angle#)
ChildIndexInParent=FindFreeChildInPArent(ParentIndex)
if ChildIndexInParent
ChildIndex=GetFreeCell(Ball())
Ball(Parentindex).ChildCount=Ball(Parentindex).ChildCount+1
// store the index of this child in the parents local array
Ball(Parentindex).Children(ChildIndexInParent) =ChildIndex
// create the child. The child is local to the parent
Ball(childIndex) = new tObjectChild
Ball(Childindex).Parent =ParentIndex
Ball(Childindex).x# =x#
Ball(Childindex).y# =y#
Ball(Childindex).Angle# =angle#
Ball(Childindex).ScaleX# =1
Ball(Childindex).ScaleY# =1
Ball(Childindex).size = 10
Ball(Childindex).colour =255
endif
EndFunction ChildIndex
Function DrawChildren(ThisParent,ParentX#,ParentY#,Angle#,ScaleX#,ScaleY#)
ca#=Cos(angle#)
sa#=Sin(angle#)
for lp=1 to MaxChildren-1
ThisChild=Ball(ThisParent).Children(lp)
if ThisChild
Colour=Ball(ThisChild).Colour
Size =Ball(ThisChild).size
X#=Ball(ThisChild).x#*ScaleX#
Y#=Ball(ThisChild).y#*ScaleY#
rotatedX#=ParentX#+( (ca#*x#)-(sa#*y#))
rotatedY#=ParentY#+( (ca#*y#)+(sa#*x#))
Ball(ThisChild).TranslatedX#=RotatedX#
Ball(ThisChild).TranslatedY#=RotatedY#
circlec RotatedX#,RotatedY#,size,true,colour
endif
next
// draw children
if Ball(ThisParent).ChildCount
for lp=1 to MaxChildren-1
ThisChild=Ball(ThisParent).Children(lp)
if ThisChild
x# =Ball(ThisChild).TranslatedX#
y# =Ball(ThisChild).TranslatedY#
DrawChildren(ThisChild,X#,Y#,wrapangle(Ball(ThisChild).Angle#,Angle#),Ball(ThisChild).ScaleX#,Ball(ThisChild).ScaleY#)
endif
next
endif
EndFunction
function LocateAbsoluteParentOffset(ThisChild)
repeat
parent =Ball(ThisChild).Parent
x#=x#+Ball(ThisChild).x#
y#=y#+Ball(ThisChild).y#
until Parent=0
EndFunction x#,y#
Function FindFreeChildInPArent(ThisParent)
for lp=1 to MaxChildren
ChildIndex=Ball(ThisParent).Children(lp)
if ChildIndex=0
exitfunction lp
endif
next
EndFunction Index