Rubyists: Just use double-quoted strings.
Lawson Kurtz, Former Senior Developer
Article Category:
Posted on
Updates
Added an additional test and test results to specifically address questions around parsing performance. (Thanks for the suggestion @JEG2.)
If you've written Ruby, you've heard it before: Use single quoted strings unless you need string interpolation.
It makes sense, right? When I instantiate strings using double quotes, the Ruby intepreter has to do extra work to figure out if it needs to perform interpolation. Since extra work means reduced performance, it seems reasonable to avoid double-quoted instantiation unless it's a necessity.
Prove It
As a huge fan of single quotes, I set out to prove just how naughty overuse of double-quoted strings really was. I built a test harness to compare the performance of code blocks, and started running tests.
The Tests
1: Fizzbuzz
A basic fizzbuzz program seemed like a good first test. So using double then single-quoted strings, I ran 100 rounds of fizzbuzzing up to n = 100,000, and compared the user CPU time of the runs with a T-test.
Results
Double-quoted string mean | 0.0872s |
Single-quoted string mean | 0.0866s |
T-test p-value | 0.4647 |
Statistically insignificant difference.
2: Instantiating a Small String
Dumbfounded by the results of the fizzbuzz tests, I thought that testing string instantiation exclusively would yield results more consistent with my original hypothesis. So I built the simplest test possible: 100 separate runs of a program that instantiates a single character string one million times.
Results
Double-quoted string mean | 0.1196s |
Single-quoted string mean | 0.1202s |
T-test p-value | 0.9087 |
Statistically insignificant difference.
3: Instantiating a Big String
Well maybe interpolation matching causes a bigger performance hit with bigger strings?
Results
Double-quoted string mean | 0.1228s |
Single-quoted string mean | 0.1237s |
T-test p-value | 0.2240 |
Statistically insignificant difference.
4: Instantiating an ENORMOUS String
Okay, so what if the string was A LOT bigger? Like, "the entire script of The Sandlot"-big?
Results
Double-quoted string mean | 0.1301s |
Single-quoted string mean | 0.1297s |
T-test p-value | 0.4746 |
Statistically insignificant difference.
5: Explicitly Testing the Parsing Process
Okay, so maybe we don't only care about runtime performance. What if we explicitly test parsing performance as well?
Results
Double-quoted string mean | 0.8939s |
Single-quoted string mean | 0.8964s |
T-test p-value | 0.3401 |
Statistically insignificant difference.
6: Testing the Test Harness
Maybe the test harness has poor sensitivity? I'll create a test comparing the instantiation of a string and a slightly bigger string and reject the harness if there's no detectable difference.
Results
String mean | 0.1214s |
Longer string mean | 0.1257s |
T-test p-value | 0.0000 |
Statistically significant difference.
Just use double-quoted strings
So if there's no meaningful performance difference between the two methods of Ruby string instantiation, shouldn't I just pick my favorite? Well, no. The absence of difference makes one better.
Since there is no measurable performance advantage for either, any time (however marginal) spent thinking or talking about a choice between the two is wasted. When you prefer single quoted strings, you have to think when you need interpolation. When you use double quoted strings, you never have to think. (I'd also add, anecdotally, that apostrophes are more prevalent in strings than double quotes, which again means less thinking when using double-quoted strings.)
Therefore always using double-quoted strings results in the least possible wasted time and effort.
TL;DR
If you're a pragmatic Ruby programmer, just use double-quoted strings. And if you're a theoretical performance devotee, well, you're probably not writing Ruby anyway.
Check out the tests and test harness, and contribute your own string tests here: https://github.com/vigetlabs/ruby-string-showdown