ProcedureReturn optimisation?

Just starting out? Need help? Post your questions and find answers here.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

ProcedureReturn optimisation?

Post by PB »

Which code block below is better to use, when considering final exe size and
speed of the procedure? I'd say the second is better due to far less code, but
it also creates a new variable (r), so how can I know for sure? Thanks.

Code: Select all

Procedure IsNumberLessThan100(n)
  If n<100
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

Debug IsNumberLessThan100(50)

Code: Select all

Procedure IsNumberLessThan100(n)
  If n<100 : r=1 : EndIf
  ProcedureReturn r
EndProcedure

Debug IsNumberLessThan100(50)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

The first one is much faster.

This one is just as fast as the first one, but smaller:

Code: Select all

Procedure IsNumberLessThan1002(n) 
  If n < 100
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure
Also take into account whether the majority of numbers are less than 100. If the majority is 100 or more, then this is much faster because the forward jump isn't taken:

Code: Select all

Procedure IsNumberLessThan1002(n) 
  If n >= 100
    ProcedureReturn 0
  EndIf
  ProcedureReturn 1
EndProcedure
Last edited by Trond on Sun Jun 10, 2007 11:24 am, edited 1 time in total.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Okay, the reason I asked is because I read somewhere once that a procedure
should only ever have 1 x ProcedureReturn, and I loaded one of my old sources
and saw 2 x ProcedureReturns in there, and wondered if it was worth changing
it to only one, like in my code examples in this topic. Any ideas on this?
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Don't change it. Only 1 procedurereturn is only recommended for readability, it is always slower.
maw

Post by maw »

This is how I do it:

Code: Select all

Procedure.l IsNumberLessThan100(n)
  If n<100
    ProcedureReturn #True
  EndIf
EndProcedure

Debug IsNumberLessThan100(50)
Letting the procedure return naturally without ProcedureReturn returns #False, has worked in all versions so far, though I'm not sure this can be counted on in the future? Fred/Freak?

Not sure if it's shorter or faster, but personally I prefer it with only one ProcedureReturn.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Yes, that's shorter and faster and should be reliable for future versions as well.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Why doesn't this work then?

Code: Select all

Procedure.l IsNumberLessThan100(n) 
  ProcedureReturn n<100
EndProcedure 

Debug IsNumberLessThan100(50)
Debug 50<100
Debug 101<100
It does in the debug lines!
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

manual
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

If you mean that in the manual it says procedurereturn with a value then why doesn't this work?

Code: Select all

Procedure.l IsNumberLessThan100(n) 
  a=n<100
  ProcedureReturn a 
EndProcedure 

Debug IsNumberLessThan100(50) 
Debug 50<100 
Debug 101<100
Also according to the manual, 'Debug - The expression can be any valid PureBasic expression, from numeric to string.'

So in the above 50<100 must be valid, therefore a=n<100 should be valid, procedurereturn a should be valid so the program should work.

I know it might be considered a boolean result and they are not implemented but in that case why does the debug command work?
jear
User
User
Posts: 20
Joined: Sun Dec 28, 2003 12:27 am
Location: Ammerland

Post by jear »

Why not Macro Is()?

Code: Select all

Procedure.l IsNumberLessThan100_0(n.l) 
  If n<100
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

Procedure.l IsNumberLessThan100_1(n.l) 
  If n<100 : ProcedureReturn #True : EndIf 
EndProcedure

Procedure.l IsNumberLessThan100_2(n.l) 
  ProcedureReturn (n<100) Or #False
EndProcedure 

Macro Is(expression)
  expression Or #False
EndMacro

Dim num.l(1000000) : For ix.l = 0 To 999999 : num(ix) = Random(200) : Next

time.l = ElapsedMilliseconds()
For ix.l = 0 To 999999
  a.l = IsNumberLessThan100_0(num(ix)) 
Next
Debug ElapsedMilliseconds() - time

time = ElapsedMilliseconds()
For ix = 0 To 999999
  a = IsNumberLessThan100_1(num(ix)) 
Next
Debug ElapsedMilliseconds() - time

time = ElapsedMilliseconds()
For ix = 0 To 999999
  a = IsNumberLessThan100_2(num(ix)) 
Next
Debug ElapsedMilliseconds() - time

time = ElapsedMilliseconds()
For ix = 0 To 999999
  a = Is(num(ix) < 100) 
Next
Debug ElapsedMilliseconds() - time
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

I know it might be considered a boolean result and they are not implemented but in that case why does the debug command work?
Pure luck.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Trond wrote:Pure luck.
Ah right, I thought it might be something technical like that.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

jear wrote:Why not Macro Is()?
When you rerun your code sample without debugger and boosting the # of tests 10x you'll see the PB's first example(IsNumberLessThan100_0) is the fastest everytime. It's about twice as fast as Macro Is().

Code: Select all

Procedure.l IsNumberLessThan100_0(n.l)
  If n<100
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

Procedure.l IsNumberLessThan100_1(n.l)
  If n<100 : ProcedureReturn #True : EndIf
EndProcedure

Procedure.l IsNumberLessThan100_2(n.l)
  ProcedureReturn (n<100) Or #False
EndProcedure

Macro Is(expression)
  expression Or #False
EndMacro

Dim num.l(10000000) : For IX.l = 0 To 9999999 : num(IX) = Random(200) : Next

time.l = ElapsedMilliseconds()
For IX.l = 0 To 9999999
  a.l = IsNumberLessThan100_0(num(IX))
Next
b.l=ElapsedMilliseconds() - time
MessageRequester("",Str(b))

time = ElapsedMilliseconds()
For IX = 0 To 9999999
  a = IsNumberLessThan100_1(num(IX))
Next
b.l=ElapsedMilliseconds() - time
MessageRequester("",Str(b))

time = ElapsedMilliseconds()
For IX = 0 To 9999999
  a = IsNumberLessThan100_2(num(IX))
Next
b.l=ElapsedMilliseconds() - time
MessageRequester("",Str(b))

time = ElapsedMilliseconds()
For IX = 0 To 9999999
  a = Is(num(IX) < 100)
Next
b.l=ElapsedMilliseconds() - time
MessageRequester("",Str(b))
maw

Post by maw »

Demivec wrote:When you rerun your code sample without debugger and boosting the # of tests 10x you'll see the PB's first example(IsNumberLessThan100_0) is the fastest everytime. It's about twice as fast as Macro Is().
Not here.. I get 110, 110, 110, 110.. And sometimes 109 or 111 on some of them..

With Core2Duo E6600, 2.4GHz, running Vista x64.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

@maw: I'm running with an AMD athlon 64 at 2.2Ghz, running XP. Which might explain the differences. I apologize for ommiting that.

When I change the line with the test data from

Code: Select all

Dim num.l(10000000) : For IX.l = 0 To 9999999 : num(IX) = Random(200) : Next
to

Code: Select all

Dim num.l(10000000) : For IX.l = 0 To 9999999 : num(IX) = Random(99) : Next
and alternatively

Code: Select all

Dim num.l(10000000) : For IX.l = 0 To 9999999 : num(IX) = Random(200)+101 : Next
or simply put make the values all greater than 100 or all less than 100 I get a definate win for the first routine for speed in both cases.

My #'s are (125, 218, 375, 250) for the test as is.
Last edited by Demivec on Mon Jun 11, 2007 6:15 am, edited 1 time in total.
Post Reply