PureBasic speed test compared to this video
PureBasic speed test compared to this video
Hi all, I'm a fan of Dave Plummer on YouTube (he wrote "Task Manager" on Windows, and lots of other Windows things) and he just posted a video about the speed of calculating prime numbers in Python, C#, and C++ (see the results here). He posted the source for the three languages on Github. My obvious question is: can someone convert one of those sources to PureBasic to compare the speed to his results? Would be very interesting to see. Make sure you post your code here to compare. Thanks!
[Edit] The test is done over 5 seconds, to compare properly with his results.
[Edit] The test is done over 5 seconds, to compare properly with his results.
Last edited by BarryG on Thu Mar 25, 2021 4:59 pm, edited 1 time in total.
Re: PureBasic speed test compared to this video
i will have a look to the codes. usually i am to slow on doing this... the professionals here will beat me with ther solutions i guess.
stay tuned.
stay tuned.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
- NicTheQuick
- Addict
- Posts: 1223
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: PureBasic speed test compared to this video
Just translated it for you:
And this is the output on my old laptop:
And in case you are curious, this is with debugger on:
I also compiled the C++ code using g++ on Linux and got this result:
As you can see it is nearly 7 times faster. I gues the main reason for that is automatic inlining of functions and better optimization for GetBit and ClearBit.
Code: Select all
EnableExplicit
Global Dim rawbits.a(0)
Global sieveSize.i
Procedure validateResults(actualCount.i)
Protected count.i
Select sieveSize
Case 10: count = 1
Case 100: count = 25
Case 1000: count = 168
Case 10000: count = 1229
Case 100000: count = 9592
Case 1000000: count = 78498
Case 10000000: count = 664579
Case 100000000: count = 5761455
Default: ProcedureReturn #False
EndSelect
ProcedureReturn Bool(count = actualCount)
EndProcedure
Procedure GetBit(index.i)
If index & 1
index / 2
ProcedureReturn rawbits(index / 8) & (1 << (index % 8))
EndIf
ProcedureReturn #False
EndProcedure
Procedure ClearBit(index.i)
If index & 1
index / 2
rawbits(index / 8) & ~(1 << (index % 8))
EndIf
EndProcedure
Procedure prime_sieve(n.i)
sieveSize = n
ReDim rawbits.a(n / 8)
FillMemory(@rawbits(0), n / 8 + 1, $ff, #PB_Ascii)
EndProcedure
Procedure runSieve()
Protected factor.i = 3
Protected q = Sqr(sieveSize)
Protected num.i
While (factor < q)
num = factor
While num < sieveSize
If GetBit(num)
factor = num
Break
EndIf
num + 1
Wend
num = factor * 3
While num < sieveSize
ClearBit(num)
num + factor * 2
Wend
factor + 2
Wend
EndProcedure
Procedure printResults(showResults.i, duration.d, passes.i)
Protected num.i
If showResults
Print("2, ")
EndIf
Protected count.i = 1
For num = 3 To sieveSize
If GetBit(num)
If showResults
Print(Str(num) + ", ")
EndIf
count + 1
EndIf
Next
If showResults
PrintN("")
EndIf
PrintN("Passes: " + passes +
", Time: " + duration + " ms" +
", Avg: " + StrD(duration / passes, 3) + " ms" +
", Limit: " + sieveSize +
", Count: " + count +
", Valid: " + Str(validateResults(count)))
EndProcedure
Procedure main(limit.i = 1000000, duration.i = 10000)
Protected passes.i = 0
Protected tStart.i = ElapsedMilliseconds()
While ElapsedMilliseconds() - tStart < duration
prime_sieve(limit)
runSieve()
passes + 1
Wend
Protected tD.i = ElapsedMilliseconds() - tStart
printResults(#False, tD, passes)
EndProcedure
OpenConsole()
main(1000000, 10000)
Input()
CloseConsole()
Code: Select all
Passes: 246, Time: 10021 ms, Avg: 40.736 ms, Limit: 1000000, Count: 78498, Valid: 1
Code: Select all
Passes: 30, Time: 10190 ms, Avg: 339.667 ms, Limit: 1000000, Count: 78498, Valid: 1
Code: Select all
Passes: 1741, Time: 10000 ms, Avg: 5.744, Limit: 1000000, Count: 78498, Valid: 1
Last edited by NicTheQuick on Thu Mar 25, 2021 4:35 pm, edited 3 times in total.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Re: PureBasic speed test compared to this video
on my maschine ....... Passes 329, Time 10004 ms, AVG= 30.407
and yet ???
and yet ???
TFT seid 1989
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMagic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak
Aktuelles Projekte : Driving School Evergarden
YouTube : Pure Basic to go
FaceBook : Temuçin SourceMagic Games
DISCORD : SourceMagic
W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak
Re: PureBasic speed test compared to this video
The test is meant to be done over a 5-second period, not 10. My result over 5 seconds is:
Passes: 182, Time: 5001 ms, Avg: 27.478 ms, Limit: 1000000, Count: 78498, Valid: 1
(And thanks for the converted code, NicTheQuick!).
Passes: 182, Time: 5001 ms, Avg: 27.478 ms, Limit: 1000000, Count: 78498, Valid: 1
(And thanks for the converted code, NicTheQuick!).
Re: PureBasic speed test compared to this video
PB 5.62 x86, debugger off:
Passes: 395, Time: 5009 ms, Avg: 12.681 ms, Limit: 1000000, Count: 78498, Valid: 1
PB 5.62 x64, debugger off:
Passes: 122, Time: 5039 ms, Avg: 41.303 ms, Limit: 1000000, Count: 78498, Valid: 1
Looks like 64-bit is slower??
(win 10 x64 - 5-year-old low-end ASUS laptop)
Passes: 395, Time: 5009 ms, Avg: 12.681 ms, Limit: 1000000, Count: 78498, Valid: 1
PB 5.62 x64, debugger off:
Passes: 122, Time: 5039 ms, Avg: 41.303 ms, Limit: 1000000, Count: 78498, Valid: 1
Looks like 64-bit is slower??
(win 10 x64 - 5-year-old low-end ASUS laptop)
Re: PureBasic speed test compared to this video
Ha! This is quite timely with v6 approaching.
Please post your OS versions and whitelisting of PB app in use.
And there is no process priority applied to the test?
Please post your OS versions and whitelisting of PB app in use.
And there is no process priority applied to the test?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
- NicTheQuick
- Addict
- Posts: 1223
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: PureBasic speed test compared to this video
With macros and the avoidance of modulo you actually can make it pretty fast. And that is what a C compiler usually does automatically for you:
Old code over 5 seconds:
New version over 5 seconds:
C-Code over 5 seconds on the same machine:
C-Code over 5 seconds with -O3 flag for best optimization:
Btw my CPU: Intel(R) Core(TM) i7-3820QM CPU @ 2.70GHz with 8MB L3 cache.
It's a Thinkpad W530.
Code: Select all
EnableExplicit
Global Dim rawbits.a(0)
Global sieveSize.i
Procedure validateResults(actualCount.i)
Protected count.i
Select sieveSize
Case 10: count = 1
Case 100: count = 25
Case 1000: count = 168
Case 10000: count = 1229
Case 100000: count = 9592
Case 1000000: count = 78498
Case 10000000: count = 664579
Case 100000000: count = 5761455
Default: ProcedureReturn #False
EndSelect
ProcedureReturn Bool(count = actualCount)
EndProcedure
Macro GetBit(index)
((index & 1) And rawbits(index >> 4) & (1 << ((index & $f) >> 1)))
EndMacro
Macro ClearBit(index)
rawbits(index >> 4) & ~(1 << ((index & $f) >> 1))
EndMacro
Procedure prime_sieve(n.i)
sieveSize = n
ReDim rawbits.a(n / 8)
FillMemory(@rawbits(0), n / 8 + 1, $ff, #PB_Ascii)
EndProcedure
Procedure runSieve()
Protected factor.i = 3
Protected q = Sqr(sieveSize)
Protected num.i
While (factor < q)
num = factor
While num < sieveSize
If GetBit(num)
factor = num
Break
EndIf
num + 1
Wend
num = factor * 3
While num < sieveSize
; We can be sure that num is always an odd number
ClearBit(num)
num + factor * 2
Wend
factor + 2
Wend
EndProcedure
Procedure printResults(showResults.i, duration.d, passes.i)
Protected num.i
If showResults
Print("2, ")
EndIf
Protected count.i = 1
For num = 3 To sieveSize
If GetBit(num)
If showResults
Print(Str(num) + ", ")
EndIf
count + 1
EndIf
Next
If showResults
PrintN("")
EndIf
PrintN("Passes: " + passes +
", Time: " + duration + " ms" +
", Avg: " + StrD(duration / passes, 3) + " ms" +
", Limit: " + sieveSize +
", Count: " + count +
", Valid: " + Str(validateResults(count)))
EndProcedure
Procedure main(limit.i = 1000000, duration.i = 5000)
Protected passes.i = 0
Protected tStart.i = ElapsedMilliseconds()
While ElapsedMilliseconds() - tStart < duration
prime_sieve(limit)
runSieve()
passes + 1
Wend
Protected tD.i = ElapsedMilliseconds() - tStart
printResults(#False, tD, passes)
EndProcedure
OpenConsole()
main(1000000, 5000)
Input()
CloseConsole()
Code: Select all
Passes: 129, Time: 5001 ms, Avg: 38.767 ms, Limit: 1000000, Count: 78498, Valid: 1
Code: Select all
Passes: 1690, Time: 5000 ms, Avg: 2.959 ms, Limit: 1000000, Count: 78498, Valid: 1
Code: Select all
Passes: 909, Time: 5000 ms, Avg: 5.501 ms, Limit: 1000000, Count: 78498, Valid: 1
Code: Select all
Passes: 4431, Time: 5000 ms, Avg: 1.128 ms, Limit: 1000000, Count: 78498, Valid: 1
It's a Thinkpad W530.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Re: PureBasic speed test compared to this video
PB needs inline procedures as manual option at least if the compiler is not smart enough to detect when to apply it.
Same as with easy byref parameters (way more BASIC than having to deal with pointers). I guess it is too much to ask for for current asm emitter logic? Too much old, sticky and cold spaghetti?
Anyway good to see that macro's saved PB's ass . They could also do with some practical extra's btw.
Same as with easy byref parameters (way more BASIC than having to deal with pointers). I guess it is too much to ask for for current asm emitter logic? Too much old, sticky and cold spaghetti?
Anyway good to see that macro's saved PB's ass . They could also do with some practical extra's btw.
Re: PureBasic speed test compared to this video
Macro's are inlined code.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
- NicTheQuick
- Addict
- Posts: 1223
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: PureBasic speed test compared to this video
Not really. Macros are more like generic programming in C(++).skywalk wrote:Macro's are inlined code.
For example you can not create Macros with a non trivial return value. This only works if the macro itself is a one liner. And then you also have the issue that parameters which are used multiple times were also evaluated multiple times. See here:
Code: Select all
Global counter = 0
Procedure count()
counter + 1
ProcedureReturn counter
EndProcedure
Macro tripleAMacro(a)
((a) + (a) + (a))
EndMacro
Procedure tripleAProcedure(a)
ProcedureReturn ((a) + (a) + (a))
EndProcedure
; Calls count() once
Debug tripleAProcedure(count())
counter = 0
; Calls count() three times
Debug tripleAMacro(count())
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Re: PureBasic speed test compared to this video
I agree, but I was referring to your macro code in the speed test. l often inline code for speed at the expense of shorter procedures.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
- NicTheQuick
- Addict
- Posts: 1223
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: PureBasic speed test compared to this video
In this case the inlining doubled the speed. If I change GetBit and ClearBit back to a procedure I get this result:skywalk wrote:I agree, but I was referring to your macro code in the speed test. l often inline code for speed at the expense of shorter procedures.
Code: Select all
Passes: 876, Time: 5002 ms, Avg: 5.710 ms, Limit: 1000000, Count: 78498, Valid: 1
If I then replace the shifts back to division (">> 4" -> "/ 16") it makes a much bigger difference:
Code: Select all
Passes: 190, Time: 5010 ms, Avg: 26.368 ms, Limit: 1000000, Count: 78498, Valid: 1
Code: Select all
Passes: 125, Time: 5013 ms, Avg: 40.104 ms, Limit: 1000000, Count: 78498, Valid: 1
But if Purebasic evolves to a compiler for C-Code instead FASM, we do not longer care about that I guess.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Re: PureBasic speed test compared to this video
@NicTheQuick:
if i understand you correctly, these are the fastest routines based on procedure, right?
@BarryG: told you (my solution was very similar to NicTheQuick's, so i refrained from publishing it.)
if i understand you correctly, these are the fastest routines based on procedure, right?
Code: Select all
; Macro GetBit(index)
; ((index & 1) And rawbits(index >> 4) & (1 << ((index & $f) >> 1)))
; EndMacro
Procedure GetBit(index.i)
If index & 1
ProcedureReturn rawbits(index >> 4) & (1 << ((index & $f) >> 1))
EndIf
ProcedureReturn #False
; If index & 1
; index / 2
; ProcedureReturn rawbits(index / 8) & (1 << (index % 8))
; EndIf
; ProcedureReturn #False
EndProcedure
; Macro ClearBit(index)
; rawbits(index >> 4) & ~(1 << ((index & $f) >> 1))
; EndMacro
Procedure ClearBit(index.i)
rawbits(index >> 4) & ~(1 << ((index & $f) >> 1))
; If index & 1
; index / 2
; rawbits(index / 8) & ~(1 << (index % 8))
; EndIf
EndProcedure
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
- NicTheQuick
- Addict
- Posts: 1223
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: PureBasic speed test compared to this video
The fastest should be these:Axolotl wrote:@NicTheQuick:
if i understand you correctly, these are the fastest routines based on procedure, right?
Code: Select all
Procedure GetBit(index)
ProcedureReturn Bool((index & 1) And rawbits(index >> 4) & (1 << ((index & $f) >> 1)))
EndProcedure
Procedure ClearBit(index)
rawbits(index >> 4) & ~(1 << ((index & $f) >> 1))
EndProcedure
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.