Re: Suche Funktion um Charakter im Memory zu zählen
Verfasst: 24.03.2010 00:28
Hm, tut mir leid aber offensichtlich habe ich mich geirrt, wobei das bei verschiedenen CPU's zu verschiedenen Zeiten kommen kann. Teste mal die neue Prozedur, die benötigt keinen Längenparameter und ein ein klein wenig schneller als die alte.
Code: Alles auswählen
Structure myFileInfo
name.s
laenge.i
StructureUnion
inhalt.s
zeiger.i
EndStructureUnion
EndStructure
Procedure.i DatenLesen(*dat.myFileInfo)
With *dat
Protected dnr = ReadFile(#PB_Any, \name)
If dnr
\laenge = Lof(dnr)
\inhalt = Space(\laenge)
\laenge = ReadData(dnr, \zeiger, \laenge)
CloseFile(dnr)
Else
MessageRequester(\name,"Konnte diese Datei nicht öffnen!")
End
EndIf
EndWith
EndProcedure
Procedure CountChar1(*Buffer.Character, BufferLength)
; von Thorium
Protected.i i, Count
For i = 1 To BufferLength
If *Buffer\c = 13
Count + 1
EndIf
*Buffer + SizeOf(Character)
Next
ProcedureReturn Count
EndProcedure
Procedure CountChar2(*pointer.Character)
; von Stargate
Protected anz
While *pointer\c
If *pointer\c = 13 : anz + 1 : EndIf
*pointer + SizeOf(Character)
Wend
ProcedureReturn anz
EndProcedure
Procedure CountChar3(pointer)
; von Bremer
Protected p = pointer - SizeOf(Character)
Protected anz
While p
p = strchr_(p + SizeOf(Character), 13)
If p: anz + 1: EndIf
Wend
ProcedureReturn anz
EndProcedure
Procedure.i CountCharAsm(*Buffer, BufferLength.i, Char.a)
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!push edi
!cld
!xor edx,edx
!mov ecx,[p.v_BufferLength+4]
!mov edi,[p.p_Buffer+4]
!mov al,[p.v_Char+4]
!align 4
!CountCharAsmLoop:
!repne scasb
!inc edx
!test ecx,ecx
!jne CountCharAsmLoop
!mov bl,[edi]
!cmp bl,al
!je CountCharAsmEnd
!dec edx
!CountCharAsmEnd:
!mov eax, edx
!pop edi
CompilerCase #PB_Processor_x64
!push rdi
!cld
!xor rdx,rdx
!mov rcx,[p.v_BufferLength+8]
!mov rdi,[p.p_Buffer+8]
!mov al,[p.v_Char+8]
!align 8
!CountCharAsmLoop:
!repne scasb
!inc rdx
!test rcx,rcx
!jne CountCharAsmLoop
!mov bl,[rdi]
!cmp bl,al
!je CountCharAsmEnd
!dec rdx
!CountCharAsmEnd:
!mov rax, rdx
!pop rdi
CompilerEndSelect
ProcedureReturn
EndProcedure
Procedure.i CountCharAsm2(*Buffer, Char.a)
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!push edi
!push esi
!xor edx,edx
!xor ebx,ebx
!xor esi,esi
!mov edi,[p.p_Buffer+8]
!mov al,[p.v_Char+8]
!align 4
!CountCharAsm2Loop:
!mov bl,[edi]
!cmp al,bl
!sete dl
!add esi,edx
!inc edi
!test bl,bl
!jne CountCharAsm2Loop
!mov eax,esi
!pop esi
!pop edi
CompilerCase #PB_Processor_x64
!push rdi
!push rsi
!xor rdx,rdx
!xor rbx,rbx
!xor rsi,rsi
!mov rdi,[p.p_Buffer+16]
!mov al,[p.v_Char+16]
!align 8
!CountCharAsm2Loop:
!mov bl,[rdi]
!cmp al,bl
!sete dl
!add rsi,rdx
!inc rdi
!test bl,bl
!jne CountCharAsm2Loop
!mov rax,rsi
!pop rsi
!pop rdi
CompilerEndSelect
ProcedureReturn
EndProcedure
datei.myFileInfo
datei\name = #PB_Compiler_Home + "Compilers\APIFunctionListing.txt"
DatenLesen(datei)
max = 500
a = GetTickCount_()
For j = 1 To max: anz = CountChar1(datei\zeiger, datei\laenge): Next
thorium = GetTickCount_() - a
i$ = Str(anz) + " thorium " + Str(thorium) + #LF$
a = GetTickCount_()
For j = 1 To max: anz = CountChar2(datei\zeiger): Next
stargate = GetTickCount_() - a
i$ + Str(anz) + " stargate " + Str(stargate) + #LF$
a = GetTickCount_()
For j = 1 To max: anz = CountChar3(datei\zeiger): Next
strchr = GetTickCount_() - a
i$ + Str(anz) + " strchr " + Str(strchr) + #LF$
a = GetTickCount_()
For j = 1 To max: anz = CountCharAsm(datei\zeiger, datei\laenge, 13): Next
SimpleAsm = GetTickCount_() - a
i$ + Str(anz) + " simples Assembler " + Str(SimpleAsm) + #LF$
a = GetTickCount_()
For j = 1 To max: anz = CountCharAsm2(datei\zeiger, 13): Next
SimpleAsm2 = GetTickCount_() - a
i$ + Str(anz) + " simples Assembler 2 " + Str(SimpleAsm2) + #LF$
MessageRequester("", i$)