Синтактичният анализ на големи JSON данни изглежда е по-бавен, отколкото би трябвало. Струва си да се определи причината и да се изпрати кръпка на авторите на Go.
Междувременно, ако можете да избегнете JSON и да използвате двоичен формат, вие не само ще избегнете този проблем; вие също така ще спечелите времето, което вашият код сега изразходва за анализиране на ASCII десетични представяния на числа в техните двоични еквиваленти на IEEE 754 (и евентуално въвеждане на грешки при закръгляне, докато правите това.)
Ако и вашият подател, и получател са написани на Go, предлагам да използвате двоичния формат на Go:gob .
Извършването на бърз тест, генериране на карта с 2000 записа, всеки срез с 1050 прости float, ми дава 20 MB JSON, който отнема 1,16 секунди, за да анализирам на моята машина.
За тези бързи бенчмаркове вземам най-доброто от три теста, но се уверявам, че измервам само действителното време за синтактичен анализ с t0 := time.Now()
преди извикването на Unmarshal и отпечатване на time.Now().Sub(t0)
след него.
Използвайки GOB, същата карта води до 18 MB данни, чието анализиране отнема 115 ms:
една десета от времето .
Вашите резултати ще варират в зависимост от това колко действителни плувки имате там. Ако вашите float имат много значими цифри, заслужаващи тяхното представяне float64, тогава 20 MB JSON ще съдържат много по-малко от моите два милиона float. В този случай разликата между JSON и GOB ще бъде все по-голяма.
Между другото, това доказва, че проблемът наистина се крие в анализатора на JSON, а не в количеството данни за синтактичен анализ, нито в структурите на паметта за създаване (тъй като и двата теста анализират ~ 20 MB данни и пресъздават едни и същи парчета от float.) Замяната на всички float с низове в JSON ми дава време за синтактичен анализ от 1,02 секунди, потвърждавайки, че преобразуването от представяне на низове в двоични float отнема определено време (в сравнение с просто преместване на байтове), но не е основният виновник.
Ако подателят и синтаксичният анализатор не са и двете Go, или ако искате да намалите производителността дори повече от GOB, трябва да използвате свой собствен персонализиран двоичен формат, или като използвате буфери на протокола, или ръчно с „кодиране/двоично“ и приятели.