I managed to improve the speed of Demivec's code a little, there's still some things that can be doe to speed thing up even more.
One idea I had but too lazy to try was to draw or rather put the data into a bitmap and copy that to the screen, should be much faster than drawing each line to the screen.
Other than that, the loop itself can still be improved some more.
In any case, there are 3 different RNG's here,
just uncomment the one you wish to test and comment the others)
All 3 in this source perform pretty similar speedwise, the spread (balance of 1's and 0's) are also pretty similar.
One of the RNG's is the Pureasic Random()
The other is a very crude Multiply With Carry I made, MWC is the basis for many RNG's out there.
The third is PureBasic's CRC32FingerPrint() a "trick" someone on the net mentioned using a lot, the result might surprise you.
All 3 are seeded using RandomSource() which basically fetches the TSC of the cpu, but you can really use anything here as well, you could use a fixed value and the sequence should be the same each time, or you could use QueryPerformanceCounter or the system time or some other source as seed.
I the test only the LSB of the random number is used, this makes the test easier, but obviously there is no way to "see" if the balance of 1's and 0's are the same higher up.
But as per the original post I made in this thread, the whole focus is on random "coin toss" behavior.
If anyone has other RNG's they'd like to share please do so,
just make sure the speed is similar to these three.
Note! None of these are really suitable for cryptography, but for games, misc apps, AI and simple simulation (I wonder what The Sims are using?)
these should be "ok".
If you want crypto level RNG's ten look at the Windows Crypt API which has a insane RNG that uses TSC + pretty much every any other damn thing that produces a unpredictable number in Windows/hardware/user etc. as it's seed, it's a huge list of sources it has.
Anyway, have fun with testing these 3 RNG's.
Code: Select all
EnableExplicit
DisableDebugger
Define.l sWidth,sHeight,sDepth,sRefresh
ExamineDesktops()
sWidth = DesktopWidth(0)
sHeight = DesktopHeight(0)
sDepth = DesktopDepth(0)
sRefresh = DesktopFrequency(0)
Procedure.i RandomSource()
!RDTSC ;Read the CPU Time Stamp Counter
ProcedureReturn ;Return the EAX register content, (32bit)
EndProcedure ;we're not using the upper half (EDX) as that hardly changes at all.
Structure ran_seed_struct
seed.l
carry.l
EndStructure
Define ran_seed.ran_seed_struct, random.l
random.l=RandomSource() ;for CRC32
RandomSeed(random) ;for Random()
ran_seed\seed=random ;for MWC()
Procedure.l MWC(*seed)
!mov ecx,dword[p.p_seed]
!mov eax,dword[ecx]
!mov edx,3373259949
!mul edx
!add eax,[ecx+4]
!adc edx,0
!mov dword[ecx],eax
!mov dword[ecx+4],edx
ProcedureReturn
EndProcedure
InitSprite()
InitKeyboard()
SetRefreshRate(sRefresh)
OpenScreen( sWidth, sHeight, sDepth, "RandomDemo3" )
Dim vert.l(sWidth - 1)
#TextColor=$FF8000
Dim color.l(8)
color(0)=RGB(255,0,128)
color(1)=RGB(128,255,0)
color(2)=RGB(0,128,255)
color(3)=RGB(0,255,128)
color(4)=RGB(192,64,64)
color(5)=RGB(192,64,192)
color(6)=RGB(64,192,192)
color(7)=RGB(64,64,192)
color(8)=RGB(0,128,255)
timeBeginPeriod_(1)
Define last.l,time.l,fps.i,lastfps$,oldfps.i,rnd.i,total.q,zeroes.q,ones.q,now.l,n.l,r.l,length.l
last=timeGetTime_()
now=last
Repeat
now=timeGetTime_()
ExamineKeyboard()
For n = 0 To sWidth - 1
;start of RNG's, uncomment the one you want to test, and comment the others out.
; r = Random(-1)&%1 ;PureBasic's RNG
; random=CRC32Fingerprint(@random,4) : r=random&%1 ;CRC32 RNG
r=MWC(ran_seed)&%1 ;Multiply With Carry RNG
;end of RNG's
rnd+1
If r
vert(n)+1
ones+1
Else
vert(n)-1
zeroes+1
EndIf
Next
StartDrawing(ScreenOutput())
Box(0,0,sWidth,sHeight,0)
If (now-last)>999
last=now
total+rnd
lastfps$=Str(fps)+" Frames/s, "+Str(rnd)+" RND/s, Total "+Str(total)+" RND, Spread "+StrD((zeroes/ones)*100.0)+" ("+Str(ones-zeroes)+")"
fps=0
rnd=0
EndIf
DrawText(0,0,lastfps$,$FFFFFF,$0)
For n = 0 To sWidth - 1
length = Abs(vert(n)) / (sWidth / 16)
If length>8 Or length<0
length=8
EndIf
Line(n, sHeight/2 - 1, 0, -vert(n),color(length))
Next
StopDrawing()
Delay(0)
FlipBuffers(#PB_Screen_NoSynchronization)
fps+1
Until KeyboardPushed(#PB_Key_Escape)
timeEndPeriod_(1)
EDIT: Fixed some spelling.