Seite 2 von 2

Verfasst: 21.10.2007 22:58
von hjbremer
Ich habs nochmal getestet und dabei einen Denkfehler von mir entdeckt. Unten die korrekte Version.

Der Vorschlag von #NULL ist in der Tat nochmal um ca 10-40% schneller als PeekC

Code: Alles auswählen

x$="h "
max=10000000

a=GetTickCount_()

For j=1 To max
  If Trim(x$)=""
     x+1
  EndIf
Next


b=GetTickCount_()
MessageRequester("",Str(b-a )+#LF$+Str(x))

;--------------------------------------

;um Faktor 10-20 schneller, je nach Länge des Strings 
;ohne Debugger getestet, mit Debugger sind die Unterschiede nicht so groß

a=GetTickCount_()

For j=1 To max
  If PeekC(@x$)='' Or PeekC(@x$)=' ' 
     xx+1
  EndIf
Next

b=GetTickCount_()
MessageRequester("",Str(b-a )+#LF$+Str(xx))

;--------------------------------------

*temp.Character 
*temp=@x$ 


a=GetTickCount_()

For j=1 To max
    If *temp\c=' ' Or *temp\c='' 
       xxx+1  
    EndIf 
  
Next

b=GetTickCount_()
MessageRequester("",Str(b-a )+#LF$+Str(xxx))
aber fast genauso schnell wie der Vorschlag von #NULL ist das

Code: Alles auswählen

a=GetTickCount_()

For j=1 To max
  z=PeekC(@x$)
  If z='' Or z=' ' 
     xx+1
  EndIf
Next

b=GetTickCount_()
MessageRequester("",Str(b-a )+#LF$+Str(xx))

Verfasst: 21.10.2007 23:50
von AND51
Euer pointern nützt euch nix, wenn ihr FOR nicht um 2 erhöht!

Jedes Zeichen in ASCII hat eine Länge von 1 Byte, euer Beispiel würde funktioneiren. Wenn ihr eure EXE aber als Unicode erstellen wollt, müsst ihr schreiben:

Code: Alles auswählen

; #NULL's korrigierte Version

For j=1 To max Step SizeOf(Character)
  z=PeekC(@x$) 
  If z='' Or z=' ' 
     xx+1 
  EndIf 
Next 
SizeOf(Character) gibt die Größe in Bytes der vordefinierten Struktur 'Character' zurück. Seine Größe beträgt 1 Byte, wenn das Programm in ASCII kompiliert wird, und 2 Byte, wenn das Programm in Unicode kompiliert wird. Der Compiler macht das automatisch. Daher müsst ihr Step bei For verwenden! Am besten nicht mannuell 1 oder 2 dahinter schreiben, sondern SizeOf(Character), alles klar?

Ich hoffe, ihr habt verstanden, was ich meine, denn wenn ich mir das grad so nochmal durchlese, weiß ich selbst nicht mehr, was ich eigentlich schreiben wollte? :?

Verfasst: 22.10.2007 00:04
von hjbremer
ich hab nix verstanden, die FOR Schleife ist doch nur zum Testen da.

Aber irgendwie macht dein Einwand Sinn, aber da es so spät ist begreife ich es nicht mehr und gehe ins Bett.

Verfasst: 22.10.2007 00:12
von Kiffi
@AND51: Du hast sicherlich übersehen, dass 'j' gar nicht innerhalb der
Schleife vorkommt ;-)

Grüße ... Kiffi

Verfasst: 22.10.2007 00:34
von AND51
> ich hab nix verstanden [...] Aber irgendwie macht dein Einwand Sinn
Das hör ich gerne! <)
Nochmal kurz:
ASCII: 1 Zeichen = 1 Byte
Unicode: 1 Zeichen = 2 Byte
Der String "lassmastecken" belegt also 26 Byte im Speicher (Unicdoe). Versuch mal, "lassma" mittels PeekS() daraus zu extrahieren:

Code: Alles auswählen

Debug PeekS(@"lassmastecken", 6)
wird so nicht gehen, wenn das Programm im Unicode-Modus ist. Also müsstest du schreiben:

Code: Alles auswählen

Debug PeekS(@"lassmastecken", 12)
Das funktioniert!

Aber das ist keine flexible Lösung! Was, wenn du dein Programm doch wieder als ASCII kompilierst? Oder du dir einen Code aus dem Forum schnappst: Woher soll der Author des Codes wissen, wie du dein Programm kompilieren willst? Also schreibt man am besten

Code: Alles auswählen

Debug PeekS(@"lassmastecken", 6*SizeOf(Character))
Wir wollen 6 Zeichen extrahieren, daher die 6. Unter ASCII wäre das genug. Unter Unicode belegt belegen 6 Zeichen aber 12 Byte Speicher, also das doppelte. SizeOf(Character) wird vom Compiler durch die Konstante 1 oder 2 ersetzt. 1 dann, wenn das Programm in ASCII kompiliert wird. 6 mal 1 = 6, also steht bei PeekS() im Endeffekt eine 6. Und ich sagte ja eben: "6 reicht." Unter Unicode wird aus SizeOf(Character) eine 2, 6 mal 2 = 12. So kannst du automatisch und dynamisch die Länge berechnen, die du extrahieren willst.


> Du hast sicherlich übersehen, dass 'j' gar nicht innerhalb der Schleife vorkommt
Ich habe es missverstanden: Ich habe den Code direkt über meinem kopiert. Ich sehe auch jetzt erst, dass der Codenicht von #NULL ist, sondern nur ein Vergleichs-Code zu #NULL seinem ist.

Du hast Recht.