3 ms·
So this isn't really deserializing JSON as some of the optimizations they are making are based on them actually targeting a JSON subset. That removes a bunch of
by olliej 5y ago
So this isn't really deserializing JSON as some of the optimizations they are making are based on them actually targeting a JSON subset. That removes a bunch of conditions and branches. Still, it's interesting, and a great example of ways handling trusted data is faster than untrusted (and I guess more importantly how people writing handlers for untrusted code can accidentally "optimize" things into security flaws :D)
That said, in my experience the real cost of JSON parsing turns out to be constructing the in memory representation of the sources. I'm sure JSON parsing for the purpose of deserializing specific types would be faster as you might be able to avoid some allocations (e.g. imagine a vector type `struct Vector { float elements[4]; }` a generic JSON representation would result in two allocations)
- beached_whale 5y agoIn my experience, doing this in C++, disabling checks is maybe 5-20%, more often around 10%, not really worth doing outside benchmarks. When it's already going at GB/s, just do the checks and use the types to get more checks. Allocations, have been a huge win. Parsing to a vector in many of the JSON benchmarks benefitted from reserving the memory up front, even if not known. In testing the cost of them, it was around 50% of the bench time. Using a bump allocator to test doubled the perf when I did it.
- olliej 5y agoOh they have other things: no white space is a big one. Depending on what they’re allowing they may be able to stop handling character escapes, etc But actual allocation ends up being killer in the JSC parser. I even tried using structure caching to speed up object creation, but it simply did not seem to matter: either there’s too little data to amortize allocations for the necessary data structures, or you’re parsing enough that simple allocations and GC start to happen (and code in c++ can’t optimize the allocations as much as the JIT can)
- beached_whale 5y agoI forget what I got when I benchmarked assuming minified, but I already optimized on that anyways. SIMDJson burns through pretty JSON but less so with minified. With C++, there are generally just less allocations, but they probably cost more, not always and I haven't measured malloc/new for small things where they often have a pool setup before going to mmap. They still lock though. But one can often just guess when the number isn't known without much cost on most systems. Choose a size like 1kb and remove the smaller up front allocations, or if the size is known reserve that.
- olliej 5y agoYeah, I was just looking at their code. It's similarly super heavy on SIMD processing, which would significantly impact the cost of the removed branches - it looks like the masochists supported escape characters. I would be interested in knowing whether they do have any benchmarks to validate the removal of error handling, etc
- beached_whale 5y agoWhen i am on a pc, I am more curious how they are using simdjson so slowly.