StringField()-Alternative

Hier könnt ihr alle Fragen zu SpiderBasic austauschen.
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35
Computerausstattung: armseliger Laptop, mit wenig RAM und noch weniger CPU-Leistung. ...und die Grafikkarte.... ....naja.. da male ich doch lieber selber.
Wohnort: nahe Wolfsburg

StringField()-Alternative

Beitrag von SBond »

Hallo Leute,

mir ist gerade aufgefallen, dass StringField nicht gerade effizient arbeitet. Bei Verdoppelung der Einträge in einem String, halbiert sich die Anzahl der geparsten Einträge pro Sekunde. Somit vervierfacht sich die Zeit, in dem ein String (mit doppelt so vielen Einträgen) geparst wird.

Code: Alles auswählen

myString.s = ""
entries.i = 16000

For x = 1 To entries
	myString + Str(x) + #CRLF$
Next

T1 = ElapsedMilliseconds()
For index = 1 To entries
	selLine.s = StringField(myString, index, #CRLF$)
Next
T2 = ElapsedMilliseconds()

Debug "Dauer: " + Str(T2-T1) + " ms"
Debug "Eintäge: " + Str(entries)
Debug "Einträge pro Sek: " + StrD(entries/((T2-T1)/1000),2)

; Eintäge: 1000  - Einträge pro Sek: 27777.78
; Eintäge: 2000  - Einträge pro Sek: 14492.75
; Eintäge: 4000  - Einträge pro Sek: 7272.73
; Eintäge: 8000  - Einträge pro Sek: 3576.22
; Eintäge: 16000 - Einträge pro Sek: 1780.75

Bei Strings mit vielen Einträgen (>10K) wird das sehr spürbar. Gibt es da eine schnellere Alternative oder muss ich mich irgendwie über Speicheroperatoren durch den String hangeln? Letzteres würde ich lieber meiden, da ich wahrscheinlich ASCI/Unicode-Unterscheidungen machen müsste.

viele Grüße,
SBond
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
Kiffi
Beiträge: 10620
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: StringField()-Alternative

Beitrag von Kiffi »

das hier ist ein wenig schneller:

Code: Alles auswählen

Define myString.s = ""
Define entries = 16000

For x = 1 To entries
  myString + Str(x) + #CRLF$
Next

Define CrLf.s = #CRLF$
Define SelLine.s
Define Value.s

T1 = ElapsedMilliseconds()

! $.each( v_mystring.split(v_crlf) , function( index, v_value ) {
SelLine = Value
! });

T2 = ElapsedMilliseconds()

Debug "Dauer: " + Str(T2-T1) + " ms"
Debug "Einträge: " + Str(entries)
Debug "Einträge pro Sek: " + StrD(entries/((T2-T1)/1000),2)
Grüße ... Peter
Hygge
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: StringField()-Alternative

Beitrag von NicTheQuick »

Das hat natürlich eine quadratische Laufzeit, weil jedes mal durch den kompletten String gelaufen wird um dann genau den Eintrag mit dem richtigen Index heraus zu nehmen.
Wenn man sowieso alle Einträge aus dem String braucht, splittet man ihn lieber direkt und packt ihn in einer Array oder eine LinkedList.

Ich habe da mal schnell etwas zusammen gebastelt, das alle Einträge eines so geteilten Strings in ein Array entpackt. Die Array-Größe wird dabei automatisch in O(1) angepasst.

Code: Alles auswählen

EnableExplicit

Procedure explode(in.s, Array out.s(1), sep.s = ",")
	Protected *i.Character = @in, *s.Character = @sep, *start = *i
	Protected index.i = 0, element.s
	
	Repeat
		If *i\c = *s\c Or *i\c = 0
			*s + SizeOf(Character)
			If *s\c = 0 Or *i\c = 0
				element =  PeekS(*start, ((*i - *start) - (*s - @sep)) / SizeOf(Character) + 1)
				If ArraySize(out()) < index
					ReDim out((ArraySize(out()) + 1) * 2 - 1)
				EndIf
				out(index) = element
				If *i\c = 0
					Break
				EndIf
				index + 1
				*start = *i + SizeOf(Character)
				*s = @sep
			EndIf
		EndIf
		*i + SizeOf(Character)
	ForEver
	
	ReDim out(index)
	
	ProcedureReturn index + 1
EndProcedure

Dim out.s(0)
Define found.i
found = explode(", hi, wie, geht,, es dir?, so", out(), ", ")

Debug "" + found + " Element gefunden."

Define i.i
For i = 0 To ArraySize(out())
	Debug "out(" + i + ") = '" + out(i) + "'"
Next
Edit: Ach Mist, das war ja schon wieder für Spiderbasic. :lol:
Bild
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35
Computerausstattung: armseliger Laptop, mit wenig RAM und noch weniger CPU-Leistung. ...und die Grafikkarte.... ....naja.. da male ich doch lieber selber.
Wohnort: nahe Wolfsburg

Re: StringField()-Alternative

Beitrag von SBond »

Kiffi hat geschrieben:das hier ist ein wenig schneller
:shock: naja "ein wenig"?! Das geht ab wie ein Zäpfchen :mrgreen:
Ich sollte wohl mal ein Crash-Kurs in JS machen :lol:

vielen Dank euch beiden :mrgreen:

viele Grüße,
Martin
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
Kiffi
Beiträge: 10620
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: StringField()-Alternative

Beitrag von Kiffi »

SBond hat geschrieben:Das geht ab wie ein Zäpfchen
es geht noch schneller (mit forEach):

Code: Alles auswählen

myString.s = ""
entries.i = 1000000

For x = 1 To entries
  myString + Str(x) + #CRLF$
Next

Define CrLf.s = #CRLF$
Define SelLine.s
Define Value.s

T1 = ElapsedMilliseconds()

! $.each( v_mystring.split(v_crlf) , function( index, v_value ) {
SelLine = Value
! });

T2 = ElapsedMilliseconds()

Debug "$.each()"
Debug "Dauer: " + Str(T2-T1) + " ms"
Debug "Einträge: " + Str(entries)
Debug "Einträge pro Sek: " + StrD(entries/((T2-T1)/1000),2)
Debug "------------------"

T1 = ElapsedMilliseconds()

! v_mystring.split(v_crlf).forEach( function( v_value, index ) {
SelLine = Value
! });

T2 = ElapsedMilliseconds()

Debug "().forEach"
Debug "Dauer: " + Str(T2-T1) + " ms"
Debug "Einträge: " + Str(entries)
Debug "Einträge pro Sek: " + StrD(entries/((T2-T1)/1000),2)
Debug "------------------"
Grüße ... Peter
Hygge
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35
Computerausstattung: armseliger Laptop, mit wenig RAM und noch weniger CPU-Leistung. ...und die Grafikkarte.... ....naja.. da male ich doch lieber selber.
Wohnort: nahe Wolfsburg

Re: StringField()-Alternative

Beitrag von SBond »

oh ha <)
Ja da bin ich wunschlos glücklich :)


Tja dann ist heute abend wohl Kalsarikännit angesagt :mrgreen:

viele Grüße,
Martin
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Antworten