Geschwindigkeit

Anfängerfragen zum Programmieren mit PureBasic.
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: Geschwindigkeit

Beitrag von ts-soft »

bobobo hat geschrieben:Das Einlesen einer unicode-ini-Datei im Umfang von 18.5 MB
Es gibt keine unicode-ini, es gibt nur ini (ASCII). Diese können max. 64 KB gross sein!

Preferences können INI-Dateien zwar lesen, aber nicht schreiben und unterscheiden sich
auch in nicht zu unterschätzendem Maße.

Man sollte für INI-Dateien, besser die WinAPI nutzen und nicht die Preferences, die sind
für eigene Programme.

INI <> Preferences, höchstens ähnlich :wink:
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
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Re: Geschwindigkeit

Beitrag von lite »

Hallo

@matbal

Danke für dein Beispiel. In deinem Code sieht man deutlich wie erschreckend langsam der Stringfield Befehl ist. Obwohl er sehr nützlich und wichtig ist.

Schneller wäre es, den String in ein Array zu splitten. Hab im Forum gesucht, aber nix brauchbares gefunden. Hatt jemand eine schnellere Lösung ?

Grüße
Lite
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Geschwindigkeit

Beitrag von bobobo »

@ts-soft
alles klar
deshalb führt die Ausführung des folgenden Codes ja auch zu einem
sofortigen vorgezogenen Weltuntergang, der ja eigentlich erst am
21.12.2012 stattfinden sollte
:mrgreen:

Code: Alles auswählen

;Achtung, die Ausführung dieses Codes führt zu einem sofortigen Weltuntergang
CreateFile(0,"d:\dickefetteIniDatei.ini")
WriteStringFormat(0,#PB_Unicode)
out.s="ClemensVonBrentano@ = Das Märchen von dem Schulmeister Klopfstock und seinen @ Söhnen"
For i=1 To 64001
  
  WriteStringN(0,ReplaceString(out,"@",Str(i)),#PB_Unicode)
Next i

CloseFile(0)
ReadFile(0,"d:\dickefetteIniDatei.ini")
Select ReadStringFormat(0)
Case    #PB_Ascii  : Debug "Kein BOM gefunden. Dies kennzeichnet üblicherweise eine normale Textdatei."
  Case #PB_UTF8   : Debug "UTF-8 BOM gefunden."
  Case #PB_Unicode: Debug "UTF-16 (Little Endian) BOM gefunden."

  Case #PB_UTF16BE: Debug "UTF-16 (Big Endian) BOM gefunden."
  Case #PB_UTF32  : Debug "UTF-32 (Little Endian) BOM gefunden."
  Case #PB_UTF32BE: Debug "UTF-32 (Big Endian) BOM gefunden."
EndSelect
CloseFile(0)
Falls der Weltuntergang dann doch nicht stattgefunden haben sollte, kann man
die Ini-Datei einfach mal anklicken.
Unter Windows wird dann einfach der Editor geöffnet und der Inhalt angezeigt :shock:

Prinzipiell hast Du natürlich Recht und UniCode ist nicht gleich Unicode
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: Geschwindigkeit

Beitrag von PMV »

lite hat geschrieben:Schneller wäre es, den String in ein Array zu splitten. Hab im Forum gesucht, aber nix brauchbares gefunden. Hatt jemand eine schnellere Lösung ?
:? wofür im Forum suchen wenn ich bereits den
Link zum passenden Thread gepostet hab? :lol:
Da hat wohl wer ein paar Posts überlesen. :wink:
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
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: Geschwindigkeit

Beitrag von ts-soft »

@lite

Du solltest beim Einlesen gleich alle Keywörter und Werte in einer strukturierten Map packen, dadurch lassen sich die Werte
wesentlich schneller abfragen bei der späteren Verwendung.

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
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Re: Geschwindigkeit

Beitrag von lite »

@PMV

Danke, deine Funktion hab ich gleich am Anfang gefunden.
Die ersten Gehversuche...

@all
Ich meinte, Stringsplit nicht nur bezogen auf die IniRead-Geschichte.
Sondern allgemein das Spliten von Strings aus dem Ram in ein Array.

Stand nicht im PureBasic-Buch, das Arrays kürzer und schneller sind als Maps ?

Lite
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: Geschwindigkeit

Beitrag von PMV »

Jedes Element eines Arrays steht direkt nach dem vorherigen Element.
Das aufrufen eines einzelnen Elementes ist also lediglich eine einfache
mathematische Rechnung: Elementgröße * Index

Bei Maps muss zum finden des passenden Elements ein Hash-Wert
gebildet werden, dessen berechnung natürlich schon um ein vielfaches
mehr ist als die einfache Multiplikation oben. Dann muss noch auf
Konflikte geprüft werden um das passende Element zu finden.
Das prüfen auf Konflikte kann sehr teuer werden, wenn es davon
viele gibt. Deswegen ist es bei Maps wichtig, eine passende Größe
bei der Initialisierung an zu geben (Standard ist 512). Wenn du nun
mehrere tausend Elemente hast, wird das zugreifen auf die Elemente
ziemlich langsam beim Standardwert.

Für Preferences würden sich Maps eigenen, die Maps beinhalten.
Jedes Mapelemente ist eine Gruppe und die untergeordnete Map
enthält die Key-Value-Pairs. Das erstellen dauert zwar etwas,
aber der Zugriff danach ist wohl kaum zu überbieten mit anderen
PB Strukturen, ohne sich dabei nen Wolf zu programmieren. :)

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
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: Geschwindigkeit

Beitrag von ts-soft »

Arrays sind beim Zugriff natürlich schneller, wenn man einen Index hat, was bei Ini- bzw. Preferences aber nicht
der Fall ist. Maps bieten hier einen direkteren Zugriff per z.B. Groupname, Keyname, ohne "selber" suchen.

PMV hat es ja bereits erklärt :wink:
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
lite
Beiträge: 122
Registriert: 27.08.2012 21:08

Re: Geschwindigkeit

Beitrag von lite »

@TS-Soft
Das mit der Preferences Sache hab ich schon verstanden. Danke

Meine zweite Frage war zum Thema "Stringsplit"

http://forums.purebasic.com/german/view ... tringsplit

Vom Ram in ein Array ?
Gibts da was schnelles ?

Lite
matbal
Beiträge: 261
Registriert: 30.03.2011 20:53

Re: Geschwindigkeit

Beitrag von matbal »

lite hat geschrieben:Vom Ram in ein Array ?
Gibts da was schnelles ?
Ob es schneller ist, weiß ich nicht. Das hatte ich mir mal zusammengebaut:

Code: Alles auswählen

; ----------------------------------------------
Procedure StringToField(*string, Array result$(1), separator$)
   ; Trennt einen String in einzelne Teile auf,
   ; und speichert die Teile in ein String-Feld
   ; Der Separator kann auch aus mehreren Bytes bestehen
   
   Protected *c.character = *string    ; Pointer auf ein Zeichen im String
   Protected *s = *c                   ; Pointer auf den Anfang des Teils
   
   Protected *sep.character = @separator$          ; Pointer auf Separator
   Protected SepLenC = Len(separator$)             ; Länge des Sep. in Zeichen
   Protected SepLenB = SepLenC * SizeOf(character) ; Länge des Sep. in Byte
   
   Protected n                         ; zählt die Einträge
   Protected a = ArraySize(result$())  ; Größe des Feldes
   
   
   Repeat
      If *c\c = *sep\c     ; könnte Separator sein
         If SepLenC = 1 Or CompareMemory(*c, *sep, SepLenB) ; Wenn es Separator ist
            ;*c\c = 0       
            
            result$(n) = PeekS(*s, (*c - *s)/SizeOf(character)) ; String bis dahin speichern  
            
            *c + SepLenB   ; Separator überspringen
            *s = *c        ; neuen Stringanfang merken
            
            n + 1          ; Feldindex erhöhen
            If n > a       ; Feld vergrößern, wenn Feld kleiner als der Index ist
               a = a*2 + 1          
               ReDim result$(a)
            EndIf
         Else
            *c + SizeOf(character)
         EndIf
         
      ElseIf *c\c = 0      ; Stringende erreicht
         result$(n) = PeekS(*s)     ; Letzter Eintrag     
         n + 1                      
         
         ReDim result$(n - 1)       ; unnötige Elemente wieder entfernen 
         ProcedureReturn n          ; Rückgabe anzahl der Elemente
         
      Else                 ; Sonst 
         *c + SizeOf(character)     ; weiter zum nächsten Zeichen 
      EndIf
   ForEver
EndProcedure
; ----------------------------------------------

Dim Feld$(0)
Define Text$ = "Ich bin//ein kleiner//Text"

Define Last
Define i

Last = StringToField(@Text$, Feld$(), "//") - 1

For i = 0 To Last
   Debug Feld$(i)
Next i
Antworten