At Iron.io, we love to give back to the coding community in our hometown of San Francisco by hosting developer events through the SF Rails Meetup and the GoSF Golang Meetup. Our March 2016 meetup was a triple threat of talks on performance optimization, dependency management, and internationalization.
Andre walked us through the history of dependencies. We’ll start with Require in 1994. Require has been around since 1997, which was the oldest commit Andre could find in CVS. Require just loads code from another file, and makes sure files are in appropriate load paths and not executed twice.
After a while, it became tedious to copy files and update load paths, so setup.rb was written. Amazingly, it still exists on the internet! It has not been updated since 2005. Setup.rb copies the idea of a unix installer. You run:
ruby setup.rb setup ruby setup.rb config ruby setup.rb install
…and copy the files to the appropriate place. Unfortunately, there were no versions and no uninstall. Ouch!
At this point, Ruby Gems happened. This was around 2003, and installing libraries was gem install / gem uninstall. As a cool side effect of making this easy, Ruby Gems added support for versioning. Hooray! Ruby Gems adds a patch to the require method to fetch the latest version of any gem from the require method call. Unfortunately gem apps don’t play well with others. I started a Rails job in 2008 and was told that they would be very impressed if I could get the app running on my laptop in seven days.
Rails tried to solve this problem. It let you say “config.gem” inside your Rails application. Ruby gems does run-time dependency resolution, and the way you solve this problem is to check the versions against each other when you install them, rather than when you run them and it’s too late. This is what Bundler does, and why it’s so awesome.
Back in the day, the way you solved activation errors was to update gem versions until they would work. This isn’t something humans are good at, but computers are great at it! It’s called dependency graph resolution.
Bundler shipped in 2010, and we’ve been making improvements since then. We’ve built a completely new API for gems to make things faster, and support for multiple sources so you can use a private gem server.
Internationalization is preparing code for an international audience. This includes copy and templates, encoding, routing and language detection, date and time, currency and payment.
Prepare early. Use keys in templates from the start; use constants and symbols instead of string values for options in lists.
Allow 20% stretching space for captions, and even more on buttons.
Every time should be stored as UTC, it’s a huge time saver later when you run into multiple time zones.
Money should always be stored as integers. Don’t store these values as floats — make sure you store the currency name as well as the value.
Always use UTF-8.
Localization is the process of adapting software to a specific locale. You’ll end up with the translation of your locale file, support for your local currency, and making sure that your graphics, references and names are culturally adequate. You also have to check for legality and tax issues.
Language codes start with Language code, then a hyphen, then the country code.
Rails has the t() translate method, as well as placeholders, pluralization, and the html-suffix. Pluralization is usually a bad idea; almost anything with concatenation of strings is a bad idea because languages work very differently.
From Rails 1 through Rails 5, the one thing that has stayed the same has been poor performance. Alexander has an old Rails application using Ruby 1.8.7. Taking that version as a benchmark at 100% performance, 2.0.0 went to 65% the time that it took to execute. 2.1 Brought us down to 37%.
What caused these optimizations? In 1.9.3, we got a better interpreter. Micro-optimizations ceased to work. In 2.1, we got an even more important upgrade, due to a generational garbage collection implementation. These type of memory optimizations are the only things that really improve performance.
Thanks so much to the attendees who came out. We’re looking forward to future installments of the SF Rails Meetup — sign up to be notified when a new meetup is scheduled.