PB function CompareMemory already highly optimized

Everything else that doesn't fall into one of the other PB categories.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

PB function CompareMemory already highly optimized

Post by mk-soft »

It was a request to find the first byte with difference.
Therefore I realized the function with CompareMemory instead of a search loop.
And that without ASM.

Update v0.02
- Added CompareMemoryInteger

Code: Select all

;-TOP
CompilerIf #PB_Compiler_Debugger
  CompilerError "Disable Debugger!"
CompilerEndIf

Structure udtArray
  StructureUnion
    b.b[0]
    i.i[0]
  EndStructureUnion
EndStructure

Procedure CompareMemoryByte(*Mem1.udtArray, *Mem2.udtArray, Size)
  Protected index
  
  If *Mem1 = 0 Or *Mem2 = 0 Or Size <= 0
    ProcedureReturn 0
  EndIf
  size - 1
  For index = 0 To size
    If *Mem1\b[index] <> *Mem2\b[index]
      ProcedureReturn index + 1
    EndIf
  Next
  ProcedureReturn 0
EndProcedure

Procedure CompareMemoryInteger(*Mem1.udtArray, *Mem2.udtArray, Size)
  Protected index, size2, start
  
  If *Mem1 = 0 Or *Mem2 = 0 Or Size <= 0
    ProcedureReturn 0
  EndIf
  If Size > SizeOf(integer)
    size2 = Size / SizeOf(integer) - 1
    For index = 0 To size2 
      If *Mem1\i[index] <> *Mem2\i[index]
        Break
      EndIf
    Next
    start = index * SizeOf(integer)
  Else
    start = 0
  EndIf
  size2 = Size - 1
  For index = start To size2
    If *Mem1\b[index] <> *Mem2\b[index]
      ProcedureReturn index + 1
      Break
    EndIf
  Next
  
  ProcedureReturn 0
EndProcedure

Procedure CompareMemoryEx(*Mem1, *Mem2, Size)
  Protected r1, start, ende, size2
  
  If *Mem1 = 0 Or *Mem2 = 0 Or Size <= 0
    ProcedureReturn 0
  EndIf
  start = *Mem1
  ende = *Mem1 + Size
  size2 = Size
  Repeat
    size2 / 2
    If size2 < 1
      size2 = 1
    EndIf
    If CompareMemory(*Mem1, *Mem2, size2)
      *Mem1 + size2
      *Mem2 + size2
    Else
      If size2 = 1
        ProcedureReturn *Mem1 - start + 1
        Break
      EndIf
    EndIf
    If *Mem1 => ende
      ProcedureReturn 0
    EndIf
  ForEver
EndProcedure

;-Test

Define.udtArray *mem1, *mem2

; Allocate Memory
size = 1024*1024*512
*mem1 = AllocateMemory(size)
RandomData(*mem1, size)
*mem2 = AllocateMemory(size)
CopyMemory(*mem1, *mem2, size)

; Change one byte
pos = 1024*1024*512 - 1 ; Last byte
;pos = 1024*1024*256 - 1 ; Middle byte
;pos = 1024*1024*128 - 1
*mem2\b[pos] = *mem2\b[pos] + 1

; ----

t1 = ElapsedMilliseconds()
r1 = CompareMemoryByte(*mem1, *mem2, size)
t2 = ElapsedMilliseconds()
s1.s + "CompareMemoryByte R1-Pos = " + r1 + " Time = " + Str(t2-t1) + #LF$

t1 = ElapsedMilliseconds()
r1 = CompareMemoryInteger(*mem1, *mem2, size)
t2 = ElapsedMilliseconds()
s1.s + "CompareMemoryInteger R1-Pos = " + r1 + " Time = " + Str(t2-t1) + #LF$

t1 = ElapsedMilliseconds()
r1 = CompareMemoryEx(*mem1, *mem2, size)
t2 = ElapsedMilliseconds()
s1.s + "CompareMemoryEx R1-Pos = " + r1 + " Time = " + Str(t2-t1)  + #LF$

t1 = ElapsedMilliseconds()
r1 = CompareMemory(*mem1, *mem2, size)
t2 = ElapsedMilliseconds()
s1.s + "CompareMemory R1-Bool = " + r1 + " Time = " + Str(t2-t1)  + #LF$

MessageRequester("Test", s1)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive