Optimize but Don’t Break

We’ll start our profiling session by writing a test and a benchmark. Why? Because optimization means making changes to the code, most often to its core part. Sometimes, optimization requires complex architectural changes. And we should be able to make substantial changes without fearing we’ll break things. This is why we need the test. We’ll use the test to make sure we didn’t break anything during optimization. Benchmarking is important because, as you’ll see later, the speedup in the profiler won’t always translate to the same improvement in the real world. So we need to measure our code’s performance before and after optimization to ensure that things got faster.

We’ll embed the test directly into the application and add the --test command-line option to run the test suite. Without the option, the program will run the profiler as before.

With --benchmark option we’ll run our code outside the profiler and measure and print the execution time.

chp4/app.rb
 
# ...
 
if​ ARGV[0] == ​"--test"
 
 
ARGV.clear
 
require ​'minitest/autorun'
 
 
class​ AppTest < MiniTest::Unit::TestCase
 
 
def​ setup
 
@parsed_data = parse_data(generate_test_data)
 
end
 
 
def​ test_parsing
 
assert_equal @parsed_data.length, 50000
 
assert @parsed_data.all? ​do​ |row|
 
row.length == 3 && row[0].class == Fixnum && row[2].class == Date
 
end
 
end
 
 
def​ test_find_youngest
 
youngest = find_youngest(@parsed_data)
 
assert @parsed_data.all? { |row| youngest >= row }
 
end
 
 
end
 
 
exit(0)
 
elsif​ ARGV[0] == ​"--benchmark"
 
 
require ​'benchmark'
 
 
data = generate_test_data
 
result = Benchmark.realtime ​do
 
people = parse_data(data)
 
find_youngest(people)
 
end
 
puts ​"%5.3f"​ % result
 
 
exit(0)
 
else
 
data = generate_test_data
 
GC.disable
 
result = RubyProf.profile ​do
 
people = parse_data(data)
 
find_youngest(people)
 
end
 
end
 
# ...

The first test_parsing test checks that we got the right number of columns and rows after parsing and that the data types were recognized correctly. The second test_youngest checks that we indeed found the latest birth date from the parsed data.

Let’s run the test and make sure it passes.

 
$ ​bundle exec ruby app.rb --test
 
# Running tests:
 
..
 
Finished tests in 5.427569s, 0.3685 tests/s, 0.5527 assertions/s.
 
2 tests, 3 assertions, 0 failures, 0 errors, 0 skips

Let’s also benchmark the application before optimization.

 
$ ​bundle exec ruby app.rb --benchmark
 
0.937
..................Content has been hidden....................

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