jason
                                
                                 jason copied to clipboard
                                
                                    jason copied to clipboard
                            
                            
                            
                        Provide "jason_native"
The idea would be to have a native implementation in either C or Rust. The package would be an optional dependency of jason. The Jason.encode/decode calls would automatically and seamlessly switch to the native code if available. This means a library author could just depend on jason and the developer of the final application could decide if they prefer the Elixir or native implementation.
Things that should be particularly nice for performance should be leveraging SIMD in escaping and some parts of parsing (similar to what is done in rapidjson).
I think this is a great idea!
Having multiple Rust binaries for popular targets will be nice as well as using Rustler.
We could also just provide some sort of build step for those comfortable in the Rust ecosystem as well.
Now that serde is on stable we can (with confidence) push out stable/safe native perf for those that chose the alternative
Yes, but we can't use serde directly - the problem is that it is not pre-emptive, so we can't use it with regular NIFs. It's true we have dirty schedulers, but I'm pretty sure using them in high concurrency situations for this could be even slower than the pure Elixir version (that statement is not confirmed by any experiments, though).
Yea that makes sense. I wonder how this could otherwise be done 🤔
The easiest way would be to maintain the parsing stack as a data structure threaded through the functions instead of using recursive calls - this means we can always interrupt, return from the functions, yield and later use that state to resume the parsing from where it was left.
@michalmuskala
Yes, but we can't use serde directly - the problem is that it is not pre-emptive
This is a bit unexpected especially as Rust is meant to be highly concurrent and I can't find a proof that serde is not thread safe.
@RumataEstor It's not about thread safety. Rust and Elixir does concurrency in different ways, Rust uses OS threads and Elixir uses lightweight processes. When serde runs it will block a scheduler until it is done running so when decoding or encoding large JSON objects you can disrupt the scheduler.
I don’t mean it’s not thread safe - it is. Preemptive means we need to be able to pause the execution of the parser/generator at arbitrary moments to yield the scheduler thread to other elixir/erlang processes.
After 5 years, I finally got around to this. Check out https://github.com/spawnfest/json_native!