Sometimes you need to investigate a performance problem on your app, or you want to see which is the fastest or more efficient of two possible algorithms. In that case, use the built-in Benchmark module, which takes minimal effort and provides great feedback. You may find it familiar if you’ve used its Ruby equivalent.
In to_s(io) in Chapter 5, you learned that appending a raw object is much faster than appending a string made by interpolation with #{} or to_s. Now that we’re in a position to prove that, let’s compare these three tasks. As you know by now, we work with IO::Memory objects to increase efficiency. Let’s see how that goes:
| require "benchmark" |
| |
| IOM = IO::Memory.new |
| |
| Benchmark.ips do |x| |
| x.report("Appending") do |
| append |
| IOM.clear |
| end |
| |
| x.report("Using to_s") do |
| to_s |
| IOM.clear |
| end |
| |
| x.report("Interpolation") do |
| interpolation |
| IOM.clear |
| end |
| end |
| |
| def append |
| IOM << 42 |
| end |
| |
| def to_s |
| IOM << 42.to_s |
| end |
| |
| def interpolation |
| IOM << "#{42}" |
| end |
We require the Benchmark module to look it up in the standard library. Then we call the Benchmark.ips method, which measures iterations per second. Each task is enveloped in a do end block and is executed a large number of times to compare them. The task is called as a method, which is overkill here, but you’d do that in a real case. The report method then shows the results in a nice interface.
Build the code for production using $ crystal build benchmarking.cr --release and execute that with: $ ./benchmarking
You’ll get results like this:
| Appending 34.06M ( 29.36ns) (± 3.97%) fastest |
| Using to_s 12.67M ( 78.92ns) (± 7.55%) 2.69× slower |
| Interpolation 2.8M (356.75ns) (± 3.84%) 12.15× slower |
This proves our statement.
Also useful is the bm method, which shows you the time usage in report form:
| Benchmark.bm do |x| |
| x.report("Appending bm") do |
| IOM.clear |
| 10_000_000.times do |
| append |
| end |
| end |
| end |
| user system total real |
| Appending bm 0.240000 0.000000 0.240000 ( 0.243686) |
With this method, you have to specify the loop yourself.
➤ a. ArrayLastElem: To get the last element of an array, which method is the fastest: using -1 as index or last?
➤ b. Building_vs_Concat: In Using String Methods in Chapter 3, we also affirmed that string building is much more performant than concatenation. Prove this through benchmarking with bm. Use a string to concatenate or append to.
3.22.71.28