sql >> Database >  >> NoSQL >> Redis

Go JSON-decodering is erg traag. Wat zou een betere manier zijn om het te doen?

Het ontleden van grote JSON-gegevens lijkt langzamer te gaan dan zou moeten. Het zou de moeite waard zijn om de oorzaak te achterhalen en een patch in te dienen bij de Go-auteurs.

Als je in de tussentijd JSON kunt vermijden en een binair formaat kunt gebruiken, vermijd je niet alleen dit probleem; u zult ook de tijd winnen die uw code nu besteedt aan het ontleden van ASCII decimale representaties van getallen in hun binaire IEEE 754-equivalenten (en mogelijk het introduceren van afrondingsfouten terwijl u dit doet.)

Als zowel uw afzender als ontvanger in Go zijn geschreven, raad ik u aan het binaire formaat van Go te gebruiken:gob .

Door een snelle test te doen, een kaart te genereren met 2000 items, elk een slice met 1050 eenvoudige floats, krijg ik 20 MB JSON, wat 1,16 sec duurt om op mijn machine te ontleden.

Voor deze snelle benchmarks neem ik het beste van drie runs, maar ik zorg ervoor dat ik alleen de werkelijke parseertijd meet, met t0 := time.Now() vóór de Unmarshal-aanroep en afdrukken time.Now().Sub(t0) daarna.

Als u GOB gebruikt, resulteert dezelfde kaart in 18 MB aan gegevens, wat 115 ms kost om te ontleden:
een tiende van de tijd .

Uw resultaten zijn afhankelijk van het aantal werkelijke drijvers dat u daar heeft. Als de jouwe floats veel significante cijfers hebben, die hun float64-representatie verdienen, dan zal 20 MB JSON veel minder bevatten dan mijn twee miljoen floats. In dat geval zal het verschil tussen JSON en GOB steeds groter worden.

Dit bewijst trouwens dat het probleem inderdaad in de JSON-parser ligt, niet in de hoeveelheid gegevens die moet worden geparseerd, noch in de geheugenstructuren die moeten worden gemaakt (omdat beide tests ~ 20 MB aan gegevens parseren en dezelfde plakjes floats opnieuw maken.) Het vervangen van alle floats door strings in de JSON geeft me een parseertijd van 1,02 sec, wat bevestigt dat de conversie van stringrepresentatie naar binaire floats een bepaalde tijd kost (vergeleken met alleen het verplaatsen van bytes) maar niet de hoofdschuldige is.

Als de afzender en de parser niet allebei Go zijn, of als je de prestatie nog verder wilt drukken dan GOB, moet je je eigen aangepaste binaire formaat gebruiken, ofwel met behulp van protocolbuffers of handmatig met "encoding/binary" en vrienden.



  1. MongoDB $sorteren

  2. MongoDB $type Aggregation Pipeline Operator

  3. Een document opvragen en al zijn subdocumenten die overeenkomen met een voorwaarde in mongodb (met spring)

  4. Fatale fout - 'Mongo'-klasse niet gevonden