isOdd() and isEven()

Started by Scaremonger, December 18, 2020, 09:29:34

Previous topic - Next topic

Scaremonger

After realising that the BMX "mod" expression is rather slow, I re-wrote my isodd() and iseven() functions in C rather than use the internal one.

My previous library functions were:
Function iseven:Int( x:Int )
Return ((x Mod 2)=0)
End Function

Function isodd:Int( x:Int )
Return Not((x Mod 2)=0)
End Function


This is my C version:
evenodd.c/* Even and Odd functions
* Si Dunford, 2020
*/
int iseven( const int n )
{
return n % 2 == 0;
}
int isodd( const int n )
{
return n % 2 != 0;
}


Finally; this is my speed test code. I also included a binary AND version that I've used in other languages for comparison:
test_evenodd.bmxSuperStrict
'EVEN and ODD testing

Import "evenodd.c"
Extern
Function iseven:Int( number:Int )
Function isodd:Int( number:Int )
EndExtern

Const REPETITION:Int = 1000000

Global start:Int, finish:Int

speedtest( "bmx_even   ", bmx_iseven )
speedtest( "bmx_odd    ", bmx_isodd )
speedtest( "binaryeven ", binaryeven )
speedtest( "binaryodd  ", binaryodd )
speedtest( "iseven     ", iseven )
speedtest( "isodd      ", isodd )

Function speedtest( descr:String, fn:Int( x:Int ) )
start = MilliSecs()
For Local n:Int = -REPETITION To REPETITION
Local result:Int = fn( n )
Next
finish = MilliSecs()
Print( descr+": "+(finish-start) )
End Function

'# Blitzmax isodd() and iseven()
'# Prefixed with "bmx_" to differentiate from new C version
Function bmx_iseven:Int( x:Int )
Return ((x Mod 2)=0)
End Function

Function bmx_isodd:Int( x:Int )
Return Not((x Mod 2)=0)
End Function

'# Binary AND versions
Function binaryeven:Int( x:Int )
Return (x & $00000001 = 0 )
Return True
End Function

Function binaryodd:Int( x:Int )
Return (x & $00000001 = 1 )
Return True
End Function


The results improved things quite a bit:
bmx_even   : 246
bmx_odd    : 234
binaryeven : 238
binaryodd  : 253
iseven     : 129
isodd      : 128


Regards,
Si...

Henri

Hi,

what if you run your test in release mode ?

-Henri
- Got 01100011 problems, but the bit ain't 00000001

Derron

https://stackoverflow.com/questions/2229107/what-is-the-fastest-way-to-find-if-a-number-is-even-or-odd


btw you can look into the .bmx folder to check out the generated C code ... I assume some overhead is adding to the bmx time.


bye
Ron

iWasAdam

how about something like:

Quotereturn (input && 1) =0;

Scaremonger

Quote from: Henri on December 18, 2020, 12:09:57
what if you run your test in release mode ?
Yep. That takes so little time I can't even get a count of it. Good call.
bmx_even   : 0
bmx_odd    : 0
binaryeven : 0
binaryodd  : 0
binaryeven2: 0
binaryodd2 : 0
iseven     : 4
isodd      : 4


Quote from: Derron on December 18, 2020, 12:50:35
https://stackoverflow.com/questions/2229107/what-is-the-fastest-way-to-find-if-a-number-is-even-or-odd
btw you can look into the .bmx folder to check out the generated C code ... I assume some overhead is adding to the bmx time.
Good article, thanks for that. I hadn't thought of looking through the MaxNG C code. Thats a good first stop for future reference.

Quote from: iWasAdam on December 18, 2020, 13:13:27
how about something like:
Quotereturn (input && 1) =0;

This is already included as binaryeven() and binaryodd().


Matty

What is the project you're working on where optimising this sort of function makes a significant speed boost?  I'm curious because in all my projects optimising is about changing the flow of a program such as reducing sizes of nested for loops etc.

Scaremonger

This came around after I had an issue converting code from python and finding that 'mod' doesn't work the same (see separate thread). It just made me question other places I'd used the expression.