Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

A decodificação Go JSON é muito lenta. Qual seria a melhor maneira de fazê-lo?


A análise de grandes dados JSON parece ser mais lenta do que deveria. Valeria a pena identificar a causa e enviar um patch para os autores do Go.

Enquanto isso, se você puder evitar o JSON e usar um formato binário, não apenas evitará esse problema; você também ganhará o tempo que seu código está gastando analisando representações decimais ASCII de números em seus equivalentes binários IEEE 754 (e possivelmente introduzindo erros de arredondamento ao fazê-lo).

Se o remetente e o destinatário estiverem escritos em Go, sugiro usar o formato binário do Go:gob .

Fazendo um teste rápido, gerando um mapa com 2000 entradas, cada uma uma fatia com 1050 floats simples, me dá 20 MB de JSON, que leva 1,16 seg para analisar na minha máquina.

Para esses benchmarks rápidos, faço a melhor de três execuções, mas me certifico de medir apenas o tempo de análise real, com t0 := time.Now() antes da chamada Unmarshal e imprimindo time.Now().Sub(t0) depois disso.

Usando GOB, o mesmo mapa resulta em 18 MB de dados, o que leva 115 ms para analisar:
um décimo do tempo .

Seus resultados irão variar dependendo de quantos floats reais você tem lá. Se seus floats tiverem muitos dígitos significativos, merecendo sua representação float64, então 20 MB de JSON conterão muito menos do que meus dois milhões de floats. Nesse caso, a diferença entre JSON e GOB será cada vez maior.

BTW, isso prova que o problema está realmente no analisador JSON, não na quantidade de dados a serem analisados, nem nas estruturas de memória a serem criadas (porque ambos os testes estão analisando ~ 20 MB de dados e recriando as mesmas fatias de floats). Substituir todos os floats por strings no JSON me dá um tempo de análise de 1,02 s, confirmando que a conversão da representação de string para floats binários leva um certo tempo (em comparação com apenas mover bytes), mas não é o principal culpado.

Se o remetente e o analisador não forem ambos Go, ou se você quiser reduzir o desempenho ainda mais do que GOB, você deve usar seu próprio formato binário personalizado, usando buffers de protocolo ou manualmente com "codificação/binário" e amigos.