logoalt Hacker News

drdexebtjlyesterday at 12:29 AM0 repliesview on HN

I don’t have any benchmarks, but it’s surprisingly relevant. Not necessarily because parsing JSON is slow, but because managing memory is slow, and you’re dealing with potentially malicious input.

A non-streaming implementation needs to copy the request from the network stack into a contiguous GC-managed char array, possibly resizing it a few times as the data is received. Then when it’s time to parse, it goes through this array and allocates an unbounded number of JsonValue nodes. For JsonString and JsonNumber, it probably needs to create defensive copies of the data instead of spans of the input array, otherwise changing the input array corrupts the tree.

That’s kinda bad under memory pressure even for benign inputs. But consider malicious inputs, such as {"x":{"x":{"x":{"x":{"x":{…}}}}}. It would make this non-streaming implementation allocate a lot of String and JsonObject instances. The allocations would total multiple times the size of the input, and would be extremely fragmented.

On the other hand, a library that does streaming and that binds to objects could parse straight from the buffers in the network stack, and could avoid allocating objects for anything that it will not need to bind.