Steve Klabnik changelog.com/posts

fast_blank: String#blank? in C

Sam Saffron is part of the team doing Discourse, an open-source Rails-based discussion platform. He’s been kicking all kinds of ass all over Ruby-land lately, but I wanted to share a specific bit of that with you. It’s a new gem, fast_blank.

Basically, due to these awesome-looking flame graphs that Sam added to his MiniProfiler gem. Here’s what it does: it samples stack traces while your app runs, and then lays them all next to each other so you can see where they’re especially deep. He has a demo here, which you can click around and check out what was going on on Discourse’s home page before Sam started working on making it faster.

Anyway, so what’s this has to do with fast_blank? Well, Sam noticed that a ton of time in Discourse’s code was being spent in String#blank?, a method which was added to Rails by _why the lucky stiff way back in the day. Sam attempted to fix it, but making it 100% compatible, yet fast, was difficult.

This lead him to notice that Ruby and Rails have different implementations of #blank?, he decided to fix the issue in Discourse by writing a #blank? in C so that it was super fast.

To use fast_blank, just add it to your Gemfile:

gem 'fast_blank'

That’s it! Your String#blank? will be faster.

Actually, that’s not quite it. Over on GitHub, Sam told me that it’s not up on Rubygems yet, but will be in a few days. For now, you need to clone it down and use Bundler’s :github option:

gem 'fast_blank', github: "SamSaffron/fast_blank"

That’s it.

Now, you may be wondering why I’m making such a big deal out of all of this. Well, this is pretty much an absolutely model open source interaction between a bunch of different projects.

  1. A performance issue was found. Rather than wonder or speculate, measurements were taken.
  2. A new tool was developed to help make sense of the measurements.
  3. Attempting to fix performance in the main project itself, with a pull request.
  4. Recognizing that there was a lot going on here, so fixing it from himself via a patch.
  5. Sharing the fix with everyone until the details in the main projects could be sorted out.

Obviously, this isn’t the end of this story. What will happen next? Will Rails and MRI end up with the same implementation? Can we make it work in Ruby as fast as the C version? Will fast_blank just replace the implementation of #blank? in MRI?

I guess you’ll have to stay tuned to find out. ;)


Discussion

Sign in or Join to comment or subscribe

Player art
  0:00 / 0:00