Seite 1 von 1

PB 5.40 Beta 3: Erster Aufruf von ComposeJSON() sehr langsam

Verfasst: 14.09.2015 23:19
von Kiffi
Hallo,

ich baue ein einfaches JSON nach folgendem Schema zusammen:

Code: Alles auswählen

{
    "records": [
        { // erster Record
            "name1": "value1",
            "name2": "value2",
            "name3": "value3",
            "name4": "value4",
            "name5": "value5"
        },
        // nächste Records...
        // [...]
    ]
}
Ist also keine komplizierte Struktur; sind nur viele Records.

Hiernach lasse ich mir das JSON mit ComposeJSON() als String zurückgeben. Dabei ist mir aufgefallen, dass ComposeJSON() relativ langsam ist.

Aus diesem Grund habe ich mir einen kleinen Geschwindigkeitstest zusammengebaut:

Code: Alles auswählen

Procedure.s JsonTest(CountRows)
	
	Protected ReturnValue.s
	Protected j, jRoot, jRows, jRow, jArray, jCol
	Protected RowCounter, CountColumns, ColumnCounter
	
	j = CreateJSON(#PB_Any)
	
	If j
		
		jRoot  = SetJSONObject(JSONValue(j))
		jRows  = AddJSONMember(jRoot, "records")
		jArray = SetJSONArray(jRows)
		
		For RowCounter = 1 To CountRows
			jRow = SetJSONObject(AddJSONElement(jArray))
			For ColumnCounter = 1 To 5
				jCol = AddJSONMember(jRow, "name" + Str(ColumnCounter))
				SetJSONString(jCol, "value" + Str(ColumnCounter))
			Next
		Next
		
		ReturnValue = ComposeJSON(j)
		
		FreeJSON(j)
		
	EndIf
	
	ProcedureReturn ReturnValue
	
EndProcedure

Define z1,z2
Define CountRows
Define Result.s

For CountRows = 100000 To 110000 Step 1000
	z1=ElapsedMilliseconds()
	JsonTest(CountRows)
	z2=ElapsedMilliseconds()
	Result + "Anzahl Zeilen: " + Str(CountRows) + " / Zeit gesamt: " + Str(z2-z1) + " (" + StrF( (z2-z1) / CountRows) + " pro Zeile)" + #CRLF$
Next

MessageRequester("!", Result)
Mit diesem Code baue ich von 100.000 Records bis 110.000 Records in 1000er Schritten jeweils ein JSON zusammen und lasse mir das Ergebnis als String zurückgeben. Ich messe dabei die einzelnen Zeiten.

Zu meiner Verwunderung habe ich folgendes Ergebnis bekommen:
Anzahl Zeilen: 100000 / Zeit gesamt: 47838 (0.4783799946 pro Zeile)
Anzahl Zeilen: 101000 / Zeit gesamt: 1995 (0.0197524745 pro Zeile)
Anzahl Zeilen: 102000 / Zeit gesamt: 2026 (0.019862745 pro Zeile)
Anzahl Zeilen: 103000 / Zeit gesamt: 2044 (0.0198446605 pro Zeile)
Anzahl Zeilen: 104000 / Zeit gesamt: 2025 (0.0194711536 pro Zeile)
Anzahl Zeilen: 105000 / Zeit gesamt: 2070 (0.0197142866 pro Zeile)
Anzahl Zeilen: 106000 / Zeit gesamt: 2101 (0.0198207553 pro Zeile)
Anzahl Zeilen: 107000 / Zeit gesamt: 2096 (0.0195887852 pro Zeile)
Anzahl Zeilen: 108000 / Zeit gesamt: 2140 (0.0198148154 pro Zeile)
Anzahl Zeilen: 109000 / Zeit gesamt: 2174 (0.0199449547 pro Zeile)
Anzahl Zeilen: 110000 / Zeit gesamt: 2128 (0.0193454549 pro Zeile)
Sprich: Der erste Aufruf ist ca. 20 (!) mal langsamer als alle darauffolgenden.

Könnt Ihr das bei Euch nachvollziehen?

Grüße ... Peter

Re: PB 5.40 Beta 3: Erster Aufruf von ComposeJSON() sehr lan

Verfasst: 14.09.2015 23:52
von freak
Das JSON wird im Buffer für String-Operationen zusammengebaut. Dieser wird beim ersten mal zunächst schrittweise vergrößert bis entsprechend Platz ist. Das lässt sich beschleunigen in dem man mit einer entsprechenden String-Operation den Buffer auf die nötige Größe bringt:

Code: Alles auswählen

Space(100000000)
Damit hat man eine große Allokation anstatt vieler einzelner Vergrößerungen.

Re: PB 5.40 Beta 3: Erster Aufruf von ComposeJSON() sehr lan

Verfasst: 15.09.2015 00:52
von Kiffi
Sauber! Jetzt läuft's flott :allright: Danke für Deine schnelle Antwort!

Grüße ... Peter