Seite 3 von 7

Re: Geschwindigkeit

Verfasst: 22.11.2012 16:56
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:

Re: Geschwindigkeit

Verfasst: 22.11.2012 19:01
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

Re: Geschwindigkeit

Verfasst: 22.11.2012 19:08
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

Re: Geschwindigkeit

Verfasst: 22.11.2012 19:18
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:

Re: Geschwindigkeit

Verfasst: 22.11.2012 19:21
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

Re: Geschwindigkeit

Verfasst: 22.11.2012 19:34
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

Re: Geschwindigkeit

Verfasst: 22.11.2012 20:05
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

Re: Geschwindigkeit

Verfasst: 22.11.2012 20:11
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:

Re: Geschwindigkeit

Verfasst: 22.11.2012 20:27
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

Re: Geschwindigkeit

Verfasst: 22.11.2012 21:04
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