High-performance JSON to GRON (greppable, flattened JSON) converter
High-performance JSON to GRON (greppable, flattened JSON) converter
Make JSON greppable super fast!
fastgron transforms JSON into discrete assignments to make it easier to grep for what you want and see the absolute 'path' to it. It eases the exploration of APIs that return large blobs of JSON but have terrible documentation.
fastgron is a high-performance JSON to GRON converter, developed in C++20, utilizing simdjson library.
It's 50x faster than gron on big files (400MB/s input / 1.8GB/s output on M1 Macbook Pro), so it makes big JSON files greppable.
$ fastgron "https://api.github.com/repos/adamritter/fastgron/commits?per_page=1" | fgrep commit.author
json[0].commit.author = {}
json[0].commit.author.name = "adamritter"
json[0].commit.author.email = "[email protected]"
json[0].commit.author.date = "2023-05-30T18:04:25Z"
fastgron can work backwards too, enabling you to turn your filtered data back into JSON:
$ fastgron "https://api.github.com/repos/adamritter/fastgron/commits?per_page=1" | fgrep commit.author | fastgron --ungron
[
{
"commit": {
"author": {
"date": "2023-05-30T18:11:03Z",
"email": "[email protected]",
"name": "adamritter"
}
}
}
]
yay -S fastgron-gitbrew install fastgron --build-from-sourcenix profile install github:adamritter/fastgron#fastgronhttp and https URLs can't yet be read directly.$ cat testdata/two.json
{
"name": "Tom",
"github": "https://github.com/tomnomnom/",
"likes": ["code", "cheese", "meat"],
"contact": {
"email": "[email protected]",
"twitter": "@TomNomNom"
}
}
$ fastgron testdata/two.json
json = {}
json.name = "Tom"
json.github = "https://github.com/tomnomnom/"
json.likes = []
json.likes[0] = "code"
json.likes[1] = "cheese"
json.likes[2] = "meat"
json.contact = {}
json.contact.email = "[email protected]"
json.contact.twitter = "@TomNomNom"
…
The file name can be - or missing, in that case the data is read from stdin.
json = []
json[0] = {}
json[0].one = 1
json[0].two = 2
json[0].three = []
json[0].three[0] = 1
json[0].three[1] = 2
json[0].three[2] = 3
json[1] = {}
json[1].one = 1
json[1].two = 2
json[1].three = []
json[1].three[0] = 1
json[1].three[1] = 2
json[1].three[2] = 3
While there's a 50x speedup for converting JSON to GRON, gron is not able to convert a 800MB file back to JSON.
It takes 8s for fastgron to convert the 840MB file back to JSON.
citylots.json can be downloaded here: https://github.com/zemirco/sf-city-lots-json/blob/master/citylots.json
…
Path finding is 18x faster than jq and 5x faster than jj:
jq: 3.252s$ time jq -cM ".features[10000].properties.LOT_NUM" < ~/Downloads/citylots.json
"091"
jq -cM ".features[10000].properties.LOT_NUM" < ~/Downloads/citylots.json 2.91s user 0.28s system 97% cpu 3.252 total
jj: 0.972s$ time jj -r features.10000.properties.LOT_NUM < ~/Downloads/citylots.json
"091"
jj -r features.10000.properties.LOT_NUM < ~/Downloads/citylots.json 0.87s user 0.71s system 161% cpu 0.972 total
fastgron: 0.176s$ time build/fastgron .features.10000.properties.LOT_NUM < ~/Downloads/citylots.json
json.features[10000].properties.LOT_NUM = "091"
build/fastgron .features.10000.properties.LOT_NUM < ~/Downloads/citylots.json 0.07s user 0.10s system 95% cpu 0.176 total
To build and run this project, you need:
nix build to build the fastgron binary locally.For a development environment, either:
direnv in your shell then approve the use of .envrc via direnv allow ornix develop.Here are the steps to build, test, and install fastgron:
apt install cmake clang libcurl4-openssl-dev libssl-dev zlib1g-dev
git clone https://github.com/adamritter/fastgron.git
cd fastgron
cmake -B build -DCMAKE_CXX_COMPILER=/usr/bin/clang++ && cmake --build build
cmake install build/
No open issues yet, or sync has not completed.