Take a Step Back

Looking at the profile again, we think we collected all the low-hanging fruit there. Row parsing is still slow, though. The first five rows in the flat profile are for functions that do that parsing. In short, we optimized individual functions, but the whole thing is still slow.

In such cases the next step in optimization is to look at the code at a higher abstraction level. In our case we’ll need to reexamine what the parsing code does. The first thing we note is that our code doesn’t take advantage of the fact that column order is predefined. The first column is always a number, the second a name, and the third a date. So instead of determining the column type in the if/else statement, we can just go ahead and parse it. The date format is also predefined—there’s no need to parse it with a regular expression. Instead we can extract date parts by their position. So, let’s try out these ideas.

chp5/app_optimized4.rb
 
def​ parse_row(row)
 
col1, col2, col3 = row.split(​","​)
 
[
 
col1.to_i,
 
col2,
 
Date.new(col3[0,4].to_i, col3[5,2].to_i, col3[8,2].to_i)
 
]
 
end

Tests pass, and the new profile looks like this:

images/src/optimization_session_parsing_rewrite_flat_profile.png

Ta-da! This code is more than two times faster! With a simple change, we eliminated regular expressions altogether. All that’s left from parsing are String#to_i and String#[]. Together they take less than 30% of execution time. That’s not bad.

Now our program is almost three times faster than it originally was. That’s already impressive, and now it’s time to decide whether it’s worth it to optimize further. That’s the decision you’ll need to make every time you do significant optimization. I think three times is good enough, and the best is the enemy of the good. So let’s stop here.

Does our optimization session ends with the decision to stop profiling? Not at all. Here comes the most important part. We’ll benchmark the program without the profiler and check whether we’ll see the same three times speedup. Here’s the new number from Benchmark.realtime:

 
$ ​bundle exec ruby app_optimized4.rb --benchmark
 
0.201

Before optimization, the execution time was 0.937 seconds. After optimization, it’s just 0.201 seconds. That’s 4.7 times faster! The real-world effect is even better than the one we saw in the profiler.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.142.194