PureBasic Forum
https://www.purebasic.fr/english/

PB function CompareMemory already highly optimized
https://www.purebasic.fr/english/viewtopic.php?f=7&t=73297
Page 1 of 1

Author:  mk-soft [ Tue Jul 30, 2019 8:44 am ]
Post subject:  PB function CompareMemory already highly optimized

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:
;-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)

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/