This time it's not a poll nor question here. But some challenge!
Imagine we have some Long or Dword we get passed from somewhere and have to split this into 3 Bytes...
The idea is from Maxer73's test-script- he wants to parse some parameters he receives from midi- and he wants it real fast. Now we got a few different attempts to split a number from Long to 3 Bytes (RBG-Reverse-Function). See this demonstration script (by Maxer73) - run it, read to see what it does - not much: splits up a few variables different ways - all the same result but different execution-times...
Which - you guess is the fastest way?
Method 1: Shifting the Bytes?
Method 2: Division?
Method 3: Peeking the bytes from memory at varptr?
Method 4: MKL$ from Value and Peek Bytes from StrPtr ?
Method 5: MKL$ and place virtual variable of adequate Type over it?
Uses "Console"
%MAX_Tests = 75000
Type data
byte0 As Byte
byte1 As Byte
byte2 As Byte
End Type
Dim Midi As data
Long MidiWord
Double tStart,tEnd,tTime 'for obtain elapsed time
'---------------------------------------------------------------------
PrintL "MidiWord conversion speed test" + Str$(%Max_Tests) + " of executions:"
PrintL
PrintL "Press a Key to start method Midi_Decode_Max"
WaitKey
tStart = Timer
For MidiWord = 1 To %Max_Tests
Midi_Decode_Max (MidiWord)
PrintL Midi.byte0 & $TAB & Midi.byte1 & $TAB & Midi.byte2
Next
tEnd = Timer : tTime = (tEnd-tStart)
PrintL CRLF & "Executed in " & tTime & " seconds" & CRLF
'---------------------------------------------------------------------
PrintL "Press a Key to start method Midi_Decode_Rene1"
WaitKey
tStart = Timer
For MidiWord = 1 To %Max_Tests
Midi_Decode_Rene1(MidiWord)
PrintL Midi.byte0 & $TAB & Midi.byte1 & $TAB & Midi.byte2
Next
tEnd = Timer : tTime = (tEnd-tStart)
PrintL CRLF & "Executed in " & tTime & " seconds" & CRLF
'---------------------------------------------------------------------
PrintL "Press a Key to start method Midi_Decode_Rene2"
WaitKey
tStart = Timer
For MidiWord = 1 To %Max_Tests
Midi_Decode_Rene2(MidiWord)
PrintL Midi.byte0 & $TAB & Midi.byte1 & $TAB & Midi.byte2
Next
tEnd = Timer : tTime = (tEnd-tStart)
PrintL CRLF & "Executed in " & tTime & " seconds" & CRLF
'---------------------------------------------------------------------
PrintL "Press a Key to start method Midi_Decode_Rene3"
WaitKey
tStart = Timer
For MidiWord = 1 To %Max_Tests
Midi_Decode_Rene3(MKL$(MidiWord))
PrintL Midi.byte0 & $TAB & Midi.byte1 & $TAB & Midi.byte2
Next
tEnd = Timer : tTime = (tEnd-tStart)
PrintL CRLF & "Executed in " & tTime & " seconds" & CRLF
'---------------------------------------------------------------------
PrintL "Press a Key to start method Midi_Decode_Rene4"
WaitKey
tStart = Timer
For MidiWord = 1 To %Max_Tests
Midi_Decode_Rene4(MKL$(MidiWord))
PrintL Midi.byte0 & $TAB & Midi.byte1 & $TAB & Midi.byte2
Next
tEnd = Timer : tTime = (tEnd-tStart)
PrintL CRLF & "Executed in " & tTime & " seconds" & CRLF
'---------------------------------------------------------------------
PrintL "Press a Key to exit"
WaitKey
Sub Midi_Decode_Max (ByVal nVal As Long)
Dim temp0,temp1,temp2 As Long = nVal
Midi.byte0 = temp0 And 255
Midi.byte1 = (SHIFT SIGNED RIGHT temp1, 8) And 255
Midi.byte2 = (SHIFT SIGNED RIGHT temp2, 16) And 255
End Sub
Sub Midi_Decode_Rene1(ByVal anyValue As Long)
Midi.byte2 = Int(anyValue / &H10000)
Midi.byte1 = Int((anyValue - &H10000 * Midi.byte2)/ &H100)
Midi.byte0 = anyValue - Midi.byte2 * &H10000 - Midi.byte1 * &H100
End Sub
Sub Midi_Decode_Rene2(ByRef someVal As Long)
Midi.byte0 = Peek(Byte,VarPtr(someVal))
Midi.byte1 = Peek(Byte,VarPtr(someVal)+ 1)
Midi.byte2 = Peek(Byte,Varptr(someVal)+ 2)
End Sub
Sub Midi_Decode_Rene3(ByVal someVal As String)
Midi.byte0 = Peek(Byte,StrPtr(someVal))
Midi.byte1 = Peek(Byte,StrPtr(someVal)+ 1)
Midi.byte2 = Peek(Byte,StrPtr(someVal)+ 2)
End Sub
Sub Midi_Decode_Rene4(ByVal someVal As String)
Local lByte As data At StrPtr(someVal)
Midi = lByte
End Sub
You know any faster method?
for comparison reasons (see image), comment lines 22, 33, 44, 55, 66 and set CONST %MAX_TESTS = 1000000
Bookmarks