Date: 02-16-2022
Return to Index
created by gbSnippets
'Compilable Example: (Jose Includes)
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
'#Debug Display On
'#Debug Error On
#Include "Win32API.inc"
%iLoopMax = 100000
Global hDlg As Dword, qFreq, qStart, qStop As QUAD, DeltaTime As Single
Function PBMain() As Long
Dialog New Pixels, 0, "Reverse Array Elements",300,300,250,200, %WS_OverlappedWindow To hDlg
Control Add Button, hDlg, 100,"SWAP Array Elements", 50,10,140,20
Control Add Button, hDlg, 200,"SWAP Element Pointers", 50,40,140,20
Control Add Button, hDlg, 300,"PEEK", 50,70,140,20
Control Add Button, hDlg, 400,"ASM_Paul", 50,100,140,20
Control Add Button, hDlg, 500,"ASM_Hutch", 50,130,140,20
Control Add Button, hDlg, 600,"Array Sort_Nathan", 50,160,140,20
Dialog Show Modal hDlg Call DlgProc
End Function
CallBack Function DlgProc() As Long
Local i As Long
Static myArray() As Long, ParentArray() As Long
Select Case Cb.Msg
Case %WM_InitDialog
QueryPerformanceFrequency qFreq
ReDim myArray(1000), ParentArray(1000)
For i = 0 To 1000 : myArray(i) = i : ParentArray(i) = i : Next i 'fake data
Case %WM_Command
Select Case Cb.Ctl
Case 100 : Reverse_SWAP_ArrayElements(myArray())
Case 200 : Reverse_SWAP_ElementsPointers(myArray())
Case 300 : Reverse_PEEK(myArray())
Case 400 : Reverse_ASM_Paul(myArray())
Case 500 : Reverse_ASM_Hutch(myArray())
Case 600 : Reverse_ArraySort_Nathan(myArray(),parentArray())
End Select
End Select
End Function
Sub Reverse_SWAP_ArrayElements(theArray() As Long)
Local i,iLoop,iMax As Long
QueryPerformanceCounter qStart
For iLoop = 0 To %iLoopMax
'============================================================
iMax = UBound(theArray)
For i = 0 To iMax\2
Swap theArray(i), theArray(iMax-i)
Next i
'============================================================
Next iLoop
QueryPerformanceCounter qStop
DeltaTime = (qStop-qStart)/qFreq
? "Reverse_ArrayElements " + Format$(DeltaTime,"0.###") & " seconds"
End Sub
Sub Reverse_SWAP_ElementsPointers(theArray() As Long)
Local i,iLoop As Long, lp,fp As Long Pointer
QueryPerformanceCounter qStart
For iLoop = 0 To %iLoopMax
'============================================================
lp = VarPtr(theArray(0))
fp = VarPtr(theArray(1000))
For i = 0 To UBound(theArray)\2
Swap @fp, @lp
Incr lp : Decr fp
Next i
'============================================================
Next iLoop
QueryPerformanceCounter qStop
DeltaTime = (qStop-qStart)/qFreq
? "Reverse_ElementsPointers " + Format$(DeltaTime,"0.###") & " seconds"
End Sub
Sub Reverse_PEEK(theArray() As Long)
Register p1 As Long, p2 As Long
Local i,temp1,temp2,iLoop As Long, lp,fp As Long Pointer
QueryPerformanceCounter qStart
For iLoop = 0 To %iLoopMax
'============================================================
lp = VarPtr(theArray(0)) : fp = VarPtr(theArray(UBound(theArray)))
p1=fp : p2=lp
For i = 0 To UBound(theArray)\2
temp1=Peek(Long,p1)
temp2=Peek(Long,p2)
Poke Long,p1,temp2
Poke Long,p2,temp1
p1 -=4 : p2 +=4
Next i
'============================================================
Next iLoop
QueryPerformanceCounter qStop
DeltaTime = (qStop-qStart)/qFreq
? "Reverse_Peek " + Format$(DeltaTime,"0.###") & " seconds"
End Sub
Function Reverse_ASM_Paul(theArray() As Long) As String
Register junk As Long, junk2 As Long
Local iLoop,LoopLimit As Long, lp,fp As Long Pointer
QueryPerformanceCounter qStart
For iLoop = 0 To %iLoopMax
'============================================================
lp = VarPtr(theArray(0)) : fp = VarPtr(theArray(UBound(theArray)))
'p1=fp : p2=lp
LoopLimit =UBound(theArray)\2
' FOR i = 0 TO UBOUND(theArray)\2
' temp1=PEEK(Long,p1)
' temp2=PEEK(Long,p2)
' POKE Long,p1,temp2
' POKE Long,p2,temp1
' p1 -=4 : p2 +=4
!mov ecx,LoopLimit 'get the loop counter into ecx
!mov esi,lp 'get the 2 pointers into esi and edi
!mov edi,fp
#Align 16
lp1:
!mov eax,[edi] 'get first item
!mov edx,[esi] 'get last item
!mov [esi],eax 'store first item in last place
!mov [edi],edx 'store last item in first place
!add esi,4 'increment pointer to first item (4 bytes per long)
!sub edi,4 'decrement pointer to last item
!dec ecx 'decrement loop counter
!jns short lp1 'if no sign (i.e. hasn't gone negative) then loop back for next one
' NEXT i
'============================================================
Next iLoop
QueryPerformanceCounter qStop
DeltaTime = (qStop-qStart)/qFreq
? "Reverse_Peek " + Format$(DeltaTime,"0.###") & " seconds"
End Function
Function Reverse_ASM_Hutch(arr() As Long) As String
#Register None
Local iLoop As Long
QueryPerformanceCounter qStart
For iLoop = 0 To %iLoopMax
'============================================================
Local parr As Dword ' array pointer
Local acnt As Dword ' array member count
Local lbnd As Dword ' lower bound of array
lbnd = LBound(arr()) ' get lowest array index
parr = VarPtr(arr(lbnd)) ' get address of 1st array member
acnt = ArrayAttr(arr(),4) ' get the array member count
! sub acnt, 1 ' correct acnt for 0 base
! mov edi, acnt ' load count into EDI
! mov esi, parr ' address of first string HANDLE in ESI
! xor ebx, ebx ' zero EBX
! mov ecx, edi ' copy EDI into ECX
! shr ecx, 1 ' INT divide by 2
' -------------------------------------------
' swap pointers from outer pair to inner pair
' -------------------------------------------
lbl0:
! mov eax, [esi+ebx*4]
! mov edx, [esi+edi*4]
! mov [esi+ebx*4], edx
! mov [esi+edi*4], eax
! add ebx, 1
! sub edi, 1
! sub ecx, 1
! jnz lbl0
'============================================================
Next iLoop
QueryPerformanceCounter qStop
DeltaTime = (qStop-qStart)/qFreq
? "Reverse_Peek " + Format$(DeltaTime,"0.###") & " seconds"
End Function
Sub Reverse_ArraySort_Nathan(theArray() As Long, pArray() As Long)
Local i,iLoop As Long
QueryPerformanceCounter qStart
For iLoop = 0 To %iLoopMax
'============================================================
If i Mod 2 = 0 Then
Array Sort pArray(), TagArray theArray(), Descend
Else
Array Sort pArray(), TagArray theArray(), Ascend
End If
'============================================================
Next iLoop
QueryPerformanceCounter qStop
DeltaTime = (qStop-qStart)/qFreq
? "Reverse_ArraySort_Nathan " + Format$(DeltaTime,"0.###") & " seconds"
End Sub
'gbs_00900
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm