New version with automatic increase by 2 for next search if it already points to a search entry:
Code: Select all
EnableExplicit
DisableDebugger
Procedure.i FindMemoryString(*Memory, String$, FindFromEnd.i=#False, ReturnOffset.i=#False, *StartPtr.Character=#Null)
Protected.i StringByteLength, Result
Protected *MemoryEnd, *Ptr.Character, *FoundPtr, *Ptr2.Character, *String.Character
StringByteLength = StringByteLength(String$)
*String = @String$
If FindFromEnd
If *StartPtr
*Ptr = *StartPtr - StringByteLength
Else
*Ptr = *Memory + MemorySize(*Memory) - StringByteLength
EndIf
Repeat
If *Ptr\c = *String\c
*Ptr2 = *Ptr + 2
*String + 2
While *Ptr2\c = *String\c
*Ptr2 + 2
*String + 2
Wend
If *String\c = #Null
*FoundPtr = *Ptr
Break
EndIf
*String = @String$
EndIf
*Ptr - 2
Until *Ptr <= *Memory
Else
*MemoryEnd = *Memory + MemorySize(*Memory) - StringByteLength
If *StartPtr
If *StartPtr\c = *String\c
*Ptr = *StartPtr + 2
Else
*Ptr = *StartPtr
EndIf
Else
*Ptr = *Memory
EndIf
Repeat
If *Ptr\c = *String\c
*Ptr2 = *Ptr + 2
*String + 2
While *Ptr2\c = *String\c
*Ptr2 + 2
*String + 2
Wend
If *String\c = #Null
*FoundPtr = *Ptr
Break
EndIf
*String = @String$
EndIf
*Ptr + 2
Until *Ptr >= *MemoryEnd
EndIf
If ReturnOffset
Result = *FoundPtr - *Memory
Else
Result = *FoundPtr
EndIf
ProcedureReturn Result
EndProcedure
Define.q StartTime, EndTime, Summ
Define HW$, Result$
Define *Memory, *Here
HW$ = "Hello World of "
*Memory = AllocateMemory(50000000)
If *Memory
Debug "Mem allocated"
PokeS(*Memory + 18205400, HW$ + "Europe !")
PokeS(*Memory + 26055450, HW$ + "America!")
PokeS(*Memory + 36750820, HW$ + "Asia !")
PokeS(*Memory + 39046460, HW$ + "Africa !")
PokeS(*Memory + 46750820, HW$ + "Oceania!")
Repeat
StartTime = ElapsedMilliseconds()
*Here = FindMemoryString(*Memory, HW$, #False, #False, *Here)
EndTime = ElapsedMilliseconds()
If *Here
Result$ + PeekS(*Here + StringByteLength(HW$), 7) + " in " + Str(EndTime - StartTime) + "ms" + #LF$
Summ + (EndTime - StartTime)
EndIf
Until Not *Here
Result$ + "Summ: " + Str(Summ) + "ms" + #LF$
Result$ + #LF$ + "Reverse" + #LF$
*Here = #Null
Summ = 0
Repeat
StartTime = ElapsedMilliseconds()
*Here = FindMemoryString(*Memory, HW$, #True, #False, *Here)
EndTime = ElapsedMilliseconds()
If *Here
Result$ + PeekS(*Here + StringByteLength(HW$), 7) + " in " + Str(EndTime - StartTime) + "ms" + #LF$
Summ + (EndTime - StartTime)
EndIf
Until Not *Here
Result$ + "Summ: " + Str(Summ) + "ms" + #LF$
FreeMemory(*Memory)
EndIf
EnableDebugger
Debug Result$
Interestingly is searching backwards much faster. At least on my PC.
forward 67ms , reverse 39ms (ASM backend)
forward 65ms , reverse 37ms (C backend)
forward 26ms , reverse 11ms (C backend optimized)