ok..
nachdem ich gestern morgen völlig übernächtigt schon mal einen code postete, ihn aber kurz danach wegen fehlern zurückzog, hier nun mein vorläufiges ergebnis.
es liefert nach ausgiebigen tests genau die gleichen werte zurück, wie die originalprozedur, ist aber mehr als 30 mal schneller. leider funktioniert das ganze nur mit dateien bis zu einer größe von 65535 Bytes. möge jemand der sich damit auskennt mir dieses verhalten erklären. auch auf sonstige fehler/verbesserungen würde ich gerne hingewiesen werden. ansonsten war es eine herausforderung, die ich nicht gedacht hätte soweit zu meistern
Code: Alles auswählen
Procedure.l FindMostWords(Mem,Length)
Dim founds.w(65535)
; For z=0 To Length-1
; bits=PeekW(Mem+z) & $FFFF
; founds.w(bits)+1
; If founds.w(bits)>summe
; summe=founds.w(bits)
; word=bits
; EndIf
; If PeekW(Mem+z+1) & $FFFF=bits
; z+1
; EndIf
; Next
;zum testen, genau wie FindMostWords2() rückwärts suchen lassen, um bei
;gleichen vorkommen von werten keine unterschiedlichen ergebnisse zu bekommen
For z=Length-1 To 0 Step -1
bits=PeekW(Mem+z) & $FFFF
founds.w(bits)+1
If founds.w(bits)>summe
summe=founds.w(bits)
word=bits
EndIf
If PeekW(Mem+z-1) & $FFFF=bits
z-1
EndIf
Next
ProcedureReturn word
EndProcedure
Procedure FindMostWords2(*Mem.l)
!Mem equ esp
!Result equ esp + 4
!Len equ esp + 8
!Founds equ esp + 12
;-#
!if ~ defined _PB_AllocateMemory@4 | defined @f
!extrn _PB_AllocateMemory@4
!@@:
!end if
;
!if ~ defined _PB_FreeMemory@4 | defined @f
!extrn _PB_FreeMemory@4
!@@:
!end if
;
!if ~ defined _PB_Memory_Heap | defined @f
!extrn _PB_Memory_Heap
!@@:
!end if
;
!if ~ defined _HeapSize@12 | defined @f
!extrn _HeapSize@12
!@@:
!end if
;-#
;Len herausfinden
!MOV Eax, dword [Mem]
!OR Eax, Eax
!JNZ @f
ProcedureReturn -1
!@@:
!PUSH Eax
!PUSH 0
!PUSH dword [_PB_Memory_Heap]
!CALL _HeapSize@12
!CMP Eax, 0
!JA @f
ProcedureReturn -1
!@@:
!MOV dword [Len], Eax
;*founds = AllocateMemory(65535 * #SizeOf_Long)
!PUSH 65535 * 4
!CALL _PB_AllocateMemory@4
!MOV dword [Founds], Eax
;Ecx = *Mem + Len
!MOV Ecx, dword [Mem]
!ADD Ecx, dword [Len]
;Edx = summe.l
!MOV Edx, 0
;-#
!DEC Ecx ;um bei der ersten abfrage nicht den speicherbereich zu überschreiten
!@@:
!DEC Ecx
!CMP Ecx, dword [Mem]
!JL @f
!MOVSX Eax, word [Ecx] ;Eax = Bits = PeekW(*Mem + übrigeLen)
!AND Eax, $FFFF ;Bits = Bits & $FFFF
!MOV Ebx, Eax ;backup für evtl neues result
!SHL Eax, 2 ;Bits * #SizeOf_Long
!ADD Eax, dword [Founds] ;Bits + *Founds
!INC dword [Eax] ;-->*Founds+(Bits*#SizeOf_Long)\l + 1
!CMP dword [Eax], Edx
!JLE @b ;if *Founds+(Bits*#SizeOf_Long)\l > summe THEN:
!INC Edx ;summe + 1
!MOV dword [Result], Ebx ;neues result
!JMP @b
!@@:
;-#
!PUSH dword [Founds]
!CALL _PB_FreeMemory@4
ProcedureReturn Result
!Restore Mem
!Restore Len
!Restore Result
!Restore Founds
EndProcedure
;-#
filesize = 65535 ;crash ab 65536
Memory = AllocateMemory(filesize)
For i = 0 To filesize
PokeB(memory + i, Random($FF))
Next
StartTime = ElapsedMilliseconds()
word = FindMostWords(Memory,filesize)
ElapsedTime = ElapsedMilliseconds()-StartTime
StartTime = ElapsedMilliseconds()
word2 = FindMostWords2(Memory)
ElapsedTime2= ElapsedMilliseconds()-StartTime
MessageRequester("Info","Benötigte Zeit: " + Str(ElapsedTime) + " ms!"+Chr(13)+"Häufigster 16Bit-Wert = $"+Hex(word) + #CRLF$ + Str(ElapsedTime2) + " ms!"+Chr(13)+"Häufigster 16Bit-Wert = $"+Hex(word2),#MB_OK|#MB_ICONINFORMATION)
(die einrückungen sind hier leider wieder total daneben, liegt aber irgendwie an der PB-IDE, denn mit japbe hatte ich das problem nie)
Edit: code korrigiert. dürfte dadurch auch noch mal schneller laufen.