brianmario / yajl-ruby

A streaming JSON parsing and encoding library for Ruby (C bindings to yajl)
http://rdoc.info/projects/brianmario/yajl-ruby
MIT License
1.48k stars 169 forks source link

Faster generation of Symbols, Fixnums, and Hashes #200

Closed jhawthorn closed 3 years ago

jhawthorn commented 3 years ago

This improves the JSON generation speed of Symbols, Fixnums, and Hashes.

Symbols are made faster by checking for T_SYMBOL and calling rb_sym2str instead of calling Symbol#to_s. This avoids a string allocation and a method lookup.

Fixnums are made faster by writing our own simple itoa (to a buffer on the stack). This avoids a string allocation, method lookup, and might be a tiny bit faster since the radix is hardcoded.

Hashes are improved by avoiding calling to_s on the keys when we have a String or Symbol, and calling rb_hash_foreach instead of iterating over keys and using rb_hash_aref. This avoids a few method lookups and allocations.

In my quick test run of benchmark/encode.rb this was approximately 30% faster.

Before

                                         user     system      total        real
Yajl::Encoder#encode (to a String)   1.471238   0.000000   1.471238 (  1.471873)

After

                                         user     system      total        real
Yajl::Encoder#encode (to a String)   0.902834   0.000000   0.902834 (  0.903391)
brianmario commented 3 years ago

Hi John! Been a while :)

This is awesome, thank you!

I'm not sure why the builds aren't finishing. I'll try and get to that when I have some time.

Speaking of, I don't really have much time for OSS these days so I could definitely use some help with projects like this one.

Really appreciate it!

eileencodes commented 3 years ago

I'm not sure why the builds aren't finishing. I'll try and get to that when I have some time.

I think it's because Travis changed. Might be worth moving to GitHub actions? I can help with that.

(Also hi @brianmario!)

brianmario commented 3 years ago

@eileencodes that would be amazing! Looks like you're already a collaborator on this repo, I just invited @jhawthorn as well.

Let me know if you have any questions about anything!

jhawthorn commented 3 years ago

Cheers Brian! 🍷 Thanks! 😁

eileencodes commented 3 years ago

It seems like the builds are only running when I push to this repo rather than my fork. I think there's something about how actions don't run on forks but I thought they ran on open PRs. For example https://github.com/brianmario/yajl-ruby/pull/203 didn't run when I pushed up to my fork but when I pushed to upstream instead it ran.

eileencodes commented 3 years ago

Oh right, we need to add pull_request to the list of on actions. I think this is fixed now.

brianmario commented 3 years ago

Thanks for getting the rest of that going!