Обновить
4K+
7
Игорь Иванюто@ihar76

Пользователь

7
Рейтинг
1
Подписчики
Отправить сообщение

вопрос очень хороший. Я по сути не нашел среди баз подходящую. Одни из проверенных, как-то подходящих -- SQLLite, но тут нюанс, sql-overhead. По скорости она не может соревноваться. Как и по простоте. Я сделал решение для проекта, где нет ограничений по структуре данных, со схемой -- нативно работаем с индексами, документы отдаем как есть (as-is). т.е. напрямую запрос -> индексы -> json -> ответ. Даже система может не знать что внутри документа. Все это решается при подготовке данных в базу. т.е. полагаемся не на логику приложения, а на логику информации. При любом изменении меняем просто подготовку информации и если нужно индексы. все.

Вот такое было требование.

Насчёт «удобнее и быстрее» с protobuf -- это действительно стоит мерить на конкретных бенчмарках, спорить здесь не буду. В рамках конкретно моего проекта тянуть protobuf с генерацией схем, кодогенерацией и т. д. было бы избыточным усложнением.

Почему не Redis или Riak? Как минимум потому, что это уже совсем другой класс решения. В моём случае задача -- embedded-хранилище, где данные и индексы работают непосредственно в памяти процесса или через mmap. Поэтому здесь я в первую очередь пытаюсь минимизировать накладные расходы самого storage layer, а не сетевого взаимодействия с отдельным сервисом.

Это не значит, что Redis/Riak или protobuf плохие решения. Просто у них другие trade-off и другая область применения.

Я давно заглядываюсь на С++, даже имел опыт работы на нем, в том числе как база для больших проектов. Поэтому приятно видеть единомышленников. Но поскольку я больше работаю с Go, сделал такой эксперимент. И действительно, как и вы, обнаружил, что гибкость такого рода решений находится на таком уровне... Правда очень сложно налаживать систему и много времени уходит на доведение.

Жалко, что не все источники данных в Go

по поводу Интересует avx1 (aka avx-128) и neon в termux на гитхабе можете создать таску. я включу в дорожную карту

как вариант go test -bench ./... -benchmem

нет, поля могут меняться местами, лишние поля, непечатные символы

тут есть хитрость. Я кормлю их грязным json. а он видимо хорошо работает с чистым. Но это даже не смешно, если честно.

goos: windows goarch: amd64 pkg: github.com/GenshIv/silentjson cpu: AMD Ryzen 9 7950X3D 16-Core Processor
SilentJSON_Solo-32 | 298 | 3998580 ns/op | 3972.91 MB/s | 60544 B/op | 3 allocs/op

SilentJSON-32 | 1885 | 605436 ns/op | 26238.97 MB/s | 20791 B/op | 27 allocs/op

EasyJSON-32 | 21 | 55023176 ns/op | 288.71 MB/s | 66938179 B/op | 700019 allocs/op

go-faster/jx-32 | 63 | 19326083 ns/op | 822.00 MB/s | 15892560 B/op | 2 allocs/op

Standard_V1-32 | 9 | 121855689 ns/op | 130.37 MB/s | 10552349 B/op | 522219 allocs/op

PASS ok github.com/GenshIv/silentjson 8.954s

отдельно json v2 приведу из прошлого теста, бо там нужно включать экспериментальную поддержку

StdJSON_v1-32 3 80785100 ns/op 196.65 MB/s 2163085 B/op 220401 allocs/op

StdJSON_v2-32 3 82894933 ns/op 191.64 MB/s 19606984 B/op 820401 allocs/op

В репозитории очень много информации, и я с удовольствием вам ее предоставлю по бенчмаркам,

напишите, какие библиотеки вам бы хотелось увидеть, я подготовлю и напишу ответ. По поводу других, надо пробовать. И я признателен всем, кто дает мне фидбек.

UPD. До этого я пробовал и json2 и Jsoniter. json2 практически на ровне с стандартным. Jsoniter намного лучше, зависит от сценариев, но от нас отстает. Единственные кто может потягаться – simd типа sonic. Но у них есть свои большие недостатки и в ключевых сценариях благодаря многопоточности (и не только) у них мало шансов

1. BenchmarkNestedComparison

*Тест последовательной десериализации сложной структуры с глубокой вложенностью, ~3 млн записей. Данные содержат экранированные строки, null-значения и неизвестные поля.

| Библиотека | Время (ns/op) | Пропускная способность | Память (B/op) | Аллокации (allocs/op) |

| SilentJSON | 790,308,800 | 640.23 MB/s | 65,368,888 | 6 |

| Sonic | 1,203,687,900 | 420.36 MB/s | 886,626,392 | 10,612,816 |

| Jsoniter | 1,490,925,000 | 339.37 MB/s | 2,045,419,120 | 28,434,294 |

| Simdjson | 1,720,019,800 | 294.17 MB/s | 5,742,331,784 | 21 |

| Buger/jsonparser | 3,430,657,000 | 147.49 MB/s | 511,510,464 | 26,433,913 |

| Standard | 4,815,193,900 | 105.08 MB/s | 162,149,888 | 13,343,235 |

2. BenchmarkLargeScaleComparison

*Десериализация большого массива, состоящего из 100 000 объектов

| Библиотека | Время (ns/op) | Пропускная способность | Память (B/op) | Аллокации (allocs/op) |

| SilentJSON | 6,113,900 | 2598.34 MB/s | 19,189,576 | 24,472 |

| SonicParallel | 11,889,000 | 1336.19 MB/s | 55,370,048 | 569,222 |

| Sonic | 34,034,900 | 466.76 MB/s | 16,217,376 | 10,004 |

| Protobuf (для сравнения) | 35,280,500 | 192.91 MB/s | 39,120,520 | 1,100,019 |

| Simdjson_AST | 56,378,700 | 281.77 MB/s | 180,495,912 | 17 |

| Buger/jsonparser | 107,575,500 | 147.67 MB/s | 20,807,936 | 1,099,990 |

| Standard | 164,591,500 | 96.52 MB/s | 3,904,224 | 509,997 |

как то так

я внес правки в статье в соответствии с данными

Справедливо, я не корректно поставил информацию. Вернее было бы считать не мегобайты, а сколько объектов у нас распарсилось.

BenchmarkLargeScaleComparison/SilentJSON-32 241 5076327 ns/op 3129.43 MB/s 82334 B/op 132 allocs/op

BenchmarkLargeScaleComparison/Protobuf-32 36 32726719 ns/op 207.96 MB/s 39120496 B/op 1100019 allocs/op

видим 241 против 36 проходов абсолютно одинаковых наборов. можете сами протестировать на своих данных

можете проверить. попытался сделать с SIMD на ваш процессор. На виртуалке скорость нет смысла тестировать. simdjson-go вообще arm не поддерживает, поэтому цифры там невалидные будут.

UPS немного отладки еще нужно. скоро выложу

Совершенно верно. Но мы имеем то что имеем. Форматы не всегда мы выбираем. Это хорошо когда продукт не зависит от внешнего бизнеса. А внешнему бизнесу важнее другие вещи.

справедливо, я добавил сравнение, не полное, но смысл понятен в описании в гите подправил график и табличку красивее. файлики по 5 записей.

LibraryThroughput (MB/s)Latency (ns/op)Memory Allocated Allocs/op

SilentJSON (Parallel) 735.98MB/s 877.7ns 25B 1

Sonic 317.21MB/s 2036ns 2632B 21

Standard (encoding/json) 84.61MB/s 7635ns 2528B 52

можно протестировать, но у меня графики линейные, и большого разлета не будет. Может просесть на процентов 30 в пике (если многозадачность не сработает). Но все равно это гораздо больше стандартных библиотек.

я могу дополнить для вашей платформы поддержку, если напишите какую. Более того, буду благодарен, если поможете протестировать в своих условиях

Очень хорошее замечание, но проблема не в анализе содержимого, а просто в том, что бы его получить. А так да, изменения тоже проверялись. На передачу данных мы никак повлиять не могли, увы.

1

Информация

В рейтинге
1 035-й
Откуда
Warszawa, Польша
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Архитектор программного обеспечения
Ведущий
SQL
PostgreSQL
Linux
Kubernetes
Golang
Java
C++
PHP
Docker