String Zeichen für Zeichen durch arbeiten

Anfängerfragen zum Programmieren mit PureBasic.
Christian H
Beiträge: 134
Registriert: 18.10.2005 10:22
Wohnort: Welschbillig

String Zeichen für Zeichen durch arbeiten

Beitrag von Christian H »

Ich such eine Möglichkeit einen String möglich schnell Zeichen für Zeichen abzuarbeiten.
Folgende Möglichkeiten habe ich bisher:

Code: Alles auswählen

Procedure  test1(Text.s) 
    TAdr.i = @Text
    
    For i = TAdr To TAdr+StringByteLength(Text)-1 Step #PB_Compiler_Unicode+1
        temp.s = Chr(PeekC(i))
    Next    
EndProcedure

Procedure  test2(Text.s) 
       
    For i = 1 To Len(Text)
        temp.s = Mid(Text,i,1)
    Next    
EndProcedure

String.s = LSet("", 1000, "@") 

StartTime1 = ElapsedMilliseconds()  
For n = 1 To 1000
  test1(String) 
Next
EndTime1 = ElapsedMilliseconds() 

StartTime2 = ElapsedMilliseconds()  
For n = 1 To 1000
  test2(String) 
Next
EndTime2 = ElapsedMilliseconds() 

MessageRequester("Zeit", "test1 = "+Str(EndTime1-StartTime1)+"ms"+#CRLF$+"test2 = "+Str(EndTime2-StartTime2)+"ms")
Warum sind beide Varianten im Unicode-Modus schneller als im ASCII-Modus?
Kennt jemand noch eine schnellere Möglichkeit?

Gruß Christian
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von Kaeru Gaman »

Kennt jemand noch eine schnellere Möglichkeit?
arbeite mit einem strukturierten pointer vom typ Char.

Code: Alles auswählen

TAdr.Char = @Text
direkten Zugriff auf das Zeichen erhältst du dann mit

Code: Alles auswählen

Char = TAdr\c
natürlich musst du dann auch TAdr erhöhen um den String durchzuackern.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von STARGÅTE »

@Kaeru Gaman
:lol: der ist gut ^^ Typ Char ^^
Das Vieh heißt Character !
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von Kaeru Gaman »

du wirst lachen, Char ist schon seit langem ein gebräuchliches Hauptwort.
haben wir in C64 Zeiten schon zu nem Zeichen gesagt.
inzwischen sogar für Charaktere in Filmen und RPGs...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Pelagio
Beiträge: 424
Registriert: 11.11.2004 17:52
Computerausstattung: AMD Ryzen 5 7600 6-Core Prozessor 3.80 GHz
16,0 GB Arbeitsspeicher
Windows 11 Pro Betriebssystem
Wohnort: Bremen

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von Pelagio »

OHO, wieder zu langsam.

Ich würde die Schleifenart ändern um Geschwindigkeit zu bekommen:

Code: Alles auswählen

Procedure  test3(Text.s) 
   Protected temp.s, tAdr.i = @text
   
   While PeekC(tAdr)<>0
      temp = Chr(PeekC(tAdr))
      tAdr + 1
   Wend
    
EndProcedure
Allerdings bin ich nicht so versiert wie Kaeru Gaman (Danke!) und STARGATE.
Zuletzt geändert von Pelagio am 01.05.2010 22:50, insgesamt 1-mal geändert.
Ohne Zeit kein Fleiß
Auf neustem Stand zu sein ist eine Kunst die nicht jeder perfektioniert [Win11Pro; PB6.20 LTS]. :allright:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von ts-soft »

Code: Alles auswählen

Procedure Test3(Text.s)
  Dim TextArray.c(Len(Text))
  CopyMemory(@Text, @TextArray(0), StringByteLength(Text))
; zum testen entkommentieren
;   For i = 0 To ArraySize(TextArray())
;     Debug Chr(TextArray(i))
;   Next
EndProcedure

Define.s Text = "Feel the ..Pure.. Power"

Test3(Text)
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Christian H
Beiträge: 134
Registriert: 18.10.2005 10:22
Wohnort: Welschbillig

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von Christian H »

Nach dem ich Pelagios Version getestet habe und feststellte dass es erheblich schneller war als meine Lösungen war ich etwas Verwirrt.
Außer dass er While : Wend Schleife und ich For : Next Schleife verwende gibt es kein wesentlichen Unterschied. Also habe ich mir ForNext mal ein wenig genauer angeschaut und festgestellt dass bei jeden Durchlauf der Teil nach TO also <Ausdruck2> abgearbeitet wird. Hätte ich mal das Handbuch ganz gelesen. :(

So ist jetzt die Variante schnell genug für mich:

Code: Alles auswählen

Procedure  test1(Text.s) 
    
    TAdr.i = @Text
    TEnd.i = TAdr+StringByteLength(Text)-SizeOf(Character)
    For i = TAdr To TEnd Step SizeOf(Character)
        temp.s = Chr(PeekC(i))
    Next
    
EndProcedure
Gruß Christian

PS:Jetzt bin ich beim schreiben unterbrochen worden. Muss ts-soft Variante noch testen
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von milan1612 »

Code: Alles auswählen

string.s = "test"
*current.Character = @string

While *current\c <> 0
  Debug Chr(*current\c)
  *current + SizeOf(Character)
Wend
Sollte die schnellste Moeglichkeit sein...
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von ts-soft »

Christian H hat geschrieben:PS:Jetzt bin ich beim schreiben unterbrochen worden. Muss ts-soft Variante noch testen
Meine ist nur Komfortable, nicht schnell.
Die schnellen Routinen liegen bei mir so zwischen 135 und 138 ms.
Somit kann ich auch den Unterschied zwischen While Wend und For Next nicht bestätigen.
Hier noch meine schnelle Routine, aber nicht schneller als die von Pelagio, nur gleich.

Code: Alles auswählen

Structure char
  c.c[0]
EndStructure

Procedure Test3(Text.s)
  Protected *char.char
  Protected i
  Protected temp.s
  
  *char = @Text
  
  For i = 0 To Len(Text) - 1
    temp = Chr(*char\c[i])
  Next
EndProcedure
Aber ausser messen willste ja irgendwas machen, somit ist so ein Array wesentlich
praktischer als diese Peekerei :mrgreen:

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Christian H
Beiträge: 134
Registriert: 18.10.2005 10:22
Wohnort: Welschbillig

Re: String Zeichen für Zeichen durch arbeiten

Beitrag von Christian H »

@ts-soft deine Array Variante ist bei mir schneller als die "Structure char"-Variante

@milan1612 deine Variante ist in etwa der Vorschlag von Kaeru Gaman und in etwa genauso schnell unter Unicode wie meine letzte Variante.
Hier noch mal zum testen
Auf meinem Rechner haben test 1,3 und 4 125ms test 2 um die 1600ms.

Code: Alles auswählen

Procedure  test1(Text.s) 
    ; Christian H
    TAdr.i = @Text
    TEnd.i = TAdr+StringByteLength(Text)-SizeOf(Character)
    For i = TAdr To TEnd Step SizeOf(Character)
        temp.s = Chr(PeekC(i))
    Next
    
EndProcedure

Structure char
  c.c[0]
EndStructure

Procedure Test2(Text.s)
  ;ts-soft

  Protected *char.char
  Protected i
  Protected temp.s
 
  *char = @Text
 
  For i = 0 To Len(Text) - 1
    temp = Chr(*char\c[i])
  Next
EndProcedure

Procedure Test3(Text.s)
  ; ts-soft Array Variante 
  Dim TextArray.c(Len(Text))
  CopyMemory(@Text, @TextArray(0), StringByteLength(Text))

  len.i = ArraySize(TextArray())
  For i = 0 To len
     temp.s = Chr( TextArray(i) )
  Next
EndProcedure

Procedure Test4(Text.s)
   ; milan1612
  
  *current.Character = @Text

  While *current\c <> 0
    temp.s = Chr(*current\c)
    *current + SizeOf(Character)
  Wend
EndProcedure

String.s = LSet("", 1000, "@") 

StartTime1 = ElapsedMilliseconds()  
For n = 1 To 1000
  test1(String) ;Christian H
Next
EndTime1 = ElapsedMilliseconds() 

StartTime2 = ElapsedMilliseconds()  
For n = 1 To 1000
  test2(String) ; ts-soft 
Next
EndTime2 = ElapsedMilliseconds() 

StartTime3 = ElapsedMilliseconds()  
For n = 1 To 1000
  test3(String)  ; ts-soft Array Variante
Next
EndTime3 = ElapsedMilliseconds() 

StartTime4 = ElapsedMilliseconds()  
For n = 1 To 1000
  test4(String)  ; milan1612 / Kaeru Gaman
Next
EndTime4 = ElapsedMilliseconds() 

message.s = "Christian H   = "+Str(EndTime1-StartTime1)+"ms"+#CRLF$
message.s + "ts-soft       = "+Str(EndTime2-StartTime2)+"ms"+#CRLF$
message.s + "ts-soft Array = "+Str(EndTime3-StartTime3)+"ms"+#CRLF$
message.s + "milan1612     = "+Str(EndTime4-StartTime4)+"ms"+#CRLF$

MessageRequester("Zeit", message.s)
; IDE Options = PureBasic 4.40 (Windows - x86)
; CursorPosition = 72
; FirstLine = 37
; Folding = -
; EnableUnicode
; DisableDebugger


Gruß Christian
Antworten