sql >> データベース >  >> NoSQL >> Redis

GoJSONのデコードは非常に遅いです。それを行うためのより良い方法は何でしょうか?

    大きなJSONデータの解析は、本来よりも遅いようです。原因を特定し、Goの作成者にパッチを送信することは価値があります。

    それまでの間、JSONを回避してバイナリ形式を使用できれば、この問題を回避できるだけではありません。また、コードが数値のASCII小数表現を同等のバイナリIEEE 754に解析するために費やしている時間も得られます(その際、丸め誤差が発生する可能性があります)。

    送信者と受信者の両方がGoで記述されている場合は、Goのバイナリ形式を使用することをお勧めします: gob

    簡単なテストを実行して、2000エントリのマップを生成し、各スライスに1050の単純なフロートを含めると、20 MBのJSONが得られます。これは、私のマシンで解析するのに1.16秒かかります。

    これらのクイックベンチマークでは、3回の実行のうち最善を尽くしますが、t0 := time.Now()を使用して、実際の解析時間のみを測定するようにしています。 Unmarshal呼び出しの前にtime.Now().Sub(t0)を出力します その後。

    GOBを使用すると、同じマップで18 MBのデータが生成され、解析に115ミリ秒かかります。
    10分の1の時間

    結果は、実際にフロートがいくつあるかによって異なります。フロートに有効数字がたくさんあり、float64表現に値する場合、20MBのJSONに含まれるフロートは200万よりはるかに少なくなります。その場合、JSONとGOBの違いはさらに大きくなります。

    ところで、これは、問題が実際にJSONパーサーにあり、解析するデータの量にも、作成するメモリ構造にもないことを証明しています(どちらのテストも、最大20 MBのデータを解析し、フロートの同じスライスを再作成するためです)。 JSONですべてのfloatを文字列に置き換えると、解析時間が1.02秒になり、文字列表現からバイナリfloatへの変換には一定の時間がかかりますが(バイトを移動するだけの場合と比較して)、主な原因ではないことが確認されます。

    送信者とパーサーの両方がGoでない場合、またはGOBよりもさらにパフォーマンスを向上させたい場合は、Protocol Buffersを使用するか、「encoding / binary」などを使用して手動で、独自にカスタマイズしたバイナリ形式を使用する必要があります。



    1. マングーススキーマで複数の値を使用する一意のドキュメント

    2. 最も人気のあるオープンソースデータベースの自動化と管理の技術を完成させる:2017 @ Somenines

    3. mongoの結果から_idを削除します

    4. Redisトランザクションと長時間実行されるLuaスクリプト