Live data from Hacker News

Building a high performance JSON parser

dave.cheney.net

21–30 of 193 posts

Re: Building a high performance JSON parser

#21

The walkthrough is very nice, how to do this if you're going to do it. If you're going for pure performance in a production environment you might take a look at Daniel Lemire's work: https://github.com/simdjson/simdjson . Or the MinIO port of it to Go: https://github.com/minio/simdjson-go .

Last time I compared the performance of various json parsers the simd one turned out to be disappointingly slow.

Re: Building a high performance JSON parser

#22
post #5

[flagged]

Exactly, it's not too hard to implement in C. The one I made never copied data, instead saved the pointer/length to the data. The user only had to Memory Map the file (or equivalent), pass that data into the parse. Only memory allocation was for the Jason nodes. This way they only paid the parsing tax (decoding doubles, etc..) if the user used that data. You hit the nail on the head

Yup and if your implementation uses a hashmap for object key -> value lookup, then I recommend allocating the hashmap after parsing the object not during to avoid continually resizing the hashmap. You can implement this by using an intrusive linked list to track your key/value JSON nodes until the time comes to allocate the hashmap. Basically when parsing an object 1. use a counter 'N' to track the number of keys, 2. link the JSON nodes representing key/value pairs into an intrusive linked list, 3. after parsing the object use 'N' to allocate a perfectly sized hashmap in one go. You can then iterate over the linked list of JSON key/value pair nodes adding them to the hashmap. You can use this same trick when parsing JSON arrays to avoid continually resizing a backing array. Alternatively, never allocate a backing array and instead use the linked list to implement an iterator.

Re: Building a high performance JSON parser

#23
post #6

Earlier quoted context omitted.

Did you even open the article? Following is literally in first paragraph > This package offers the same high level json.Decoder API but higher throughput and reduced allocations

How does that contradict what the parent poster says? I think it's very weird to call something "high performance" when it looks like it's maybe 15-20% of the performance of a simdjson in c++. This is not "going from normal performance to high performance", this going from "very subpar" to "subpar"

Ok but how many teams are building web APIs in C++?

Re: Building a high performance JSON parser

#25
post #24

nowadays I am more interested in a "forgiving" JSON/YAML parser, that would recover from LLM errors, is there such a thing?

If the LLM did such a bad job that the syntax is wrong, do you really trust the data inside?

Forgiving parsers/lexers are common in language compilers for languages like rust or C# or typescript, you may want to investigate typescript in particular since it's applicable to JSON syntax. Maybe you could repurpose their parser.

Re: Building a high performance JSON parser

#26

The walkthrough is very nice, how to do this if you're going to do it. If you're going for pure performance in a production environment you might take a look at Daniel Lemire's work: https://github.com/simdjson/simdjson . Or the MinIO port of it to Go: https://github.com/minio/simdjson-go .

If your JSON always looks the same you can also do better than general JSON parsers.

I wonder: can fast, special-case JSON parsers be dynamically autogenerated from JSON Schemas?

Perhaps some macro-ridden Rust monstrosity that spits out specialised parsers at compile time, dynamically…

Re: Building a high performance JSON parser

#27
post #6

Earlier quoted context omitted.

Did you even open the article? Following is literally in first paragraph > This package offers the same high level json.Decoder API but higher throughput and reduced allocations

How does that contradict what the parent poster says? I think it's very weird to call something "high performance" when it looks like it's maybe 15-20% of the performance of a simdjson in c++. This is not "going from normal performance to high performance", this going from "very subpar" to "subpar"

Par is different for different stacks. It's reasonable for someone to treat their standard library's JSON parser as "par", given that that's the parser that most of their peers will be using, even if there are faster options that are commonly used in other stacks.

Re: Building a high performance JSON parser

#28

Earlier quoted context omitted.

If your JSON always looks the same you can also do better than general JSON parsers.

I wonder: can fast, special-case JSON parsers be dynamically autogenerated from JSON Schemas? Perhaps some macro-ridden Rust monstrosity that spits out specialised parsers at compile time, dynamically…

For json schema specifically there are some tools like go-jsonschema[1] but I've never used them personally. But you can use something like ffjson[2] in go to generate a static serialize/deserialize function based on a struct definition.

[1] https://github.com/omissis/go-jsonschema [2] https://github.com/pquerna/ffjson

Re: Building a high performance JSON parser

#29

The walkthrough is very nice, how to do this if you're going to do it. If you're going for pure performance in a production environment you might take a look at Daniel Lemire's work: https://github.com/simdjson/simdjson . Or the MinIO port of it to Go: https://github.com/minio/simdjson-go .

If your JSON always looks the same you can also do better than general JSON parsers.

You might also move to something other than JSON if parsing it is a significant part of your workload.

Re: Building a high performance JSON parser

#30
post #5

[flagged]

Exactly, it's not too hard to implement in C. The one I made never copied data, instead saved the pointer/length to the data. The user only had to Memory Map the file (or equivalent), pass that data into the parse. Only memory allocation was for the Jason nodes. This way they only paid the parsing tax (decoding doubles, etc..) if the user used that data. You hit the nail on the head

> The user only had to Memory Map the file (or equivalent)

Having done this myself, it's a massive cheat code because your bottleneck is almost always i/o and memory mapped i/o is orders of magnitude faster than sequential calls to read().

But that said it's not always appropriate. You can have gigabytes of JSON to parse, and the JSON might be available over the network, and your service might be running on a small node with limited memory. Memory mapping here adds quite a lot of latency and cost to the system. A very fast streaming JSON decoder is the move here.

Post reply on HN