Is Ruby 2.3 Faster? Nested Iterator Performance
Ruby 2.3 was released last month with yet another bunch of performance improvements. But is it really faster than 2.2? Let's take a look.
This is the first post in my series about Ruby 2.3 performance. This time we'll look at nested iterator performance.
What Is Wrong with Nested Iterators?
Most people don't know about this problem, but some iterators create extra objects. For example, every call to
Array#each_with_index produces two extra Ruby objects. This doesn't sound like a big deal until you do that in the nested loop. Look at this example:
How many objects does this example create? Of course, it allocates 10001 arrays. But, surprisingly, you will also see 20000 extra objects when you run this with Ruby 2.2 or earlier.
This is bad for performance. Extra objects add more work for the garbage collector. That results in extra GC cycles that, in turn, slow down your application.
I saw this in my code when the seemingly innocent nested loop added 1.5 seconds of execution time because of additional GC cycles.
Which Iterators Are Bad?
Note, the comparison table in the book has an incorrect header. It's not the comparison between Enum, Array, and Range. I compare Array, Range, and Hash in the book as well as in the example above.
I also have the code that you can run to demonstrate the problem and get the complete iterator performance comparison table for yourself.
Is Ruby 2.3 Faster?
Immediately after Ruby 2.3 was released, my readers told me the
each_with_index example above reports 0 additional objects with Ruby 2.3.
Were iterators optimized? It turned out they were not. Ruby 2.3 internally still creates objects. It's just the object type that changed from T_NODE to T_IMEMO. So this code will expose the bad iterator behavior with Ruby 2.3:
If you're interested in details, look at the commit into Ruby source code that changed it.
Verdict: Not Faster
Some iterators continue to create additional objects. Their use in nested loops will slow down your code.
|Next:||Is Ruby 2.3 Faster? Date Parsing Performance|
|Previous:||Why Read the Ruby Performance Optimization Book|