Performance
| Benchmark stdlib | |
| Magic frozen_string_literal comment | |
| Avoid garbage | |
| Measure first |
Benchmark stdlib
Guesses about speed are often wrong, so measure with the benchmark library. The bm helper runs each report block and prints timings.
Compare two approaches side by side and keep the faster one only when the difference survives repeated runs.
require "benchmark"
Benchmark.bm do |x|
x.report("plus:") { 1000.times { "a" + "b" } }
end
Magic frozen_string_literal comment
Every string literal normally allocates a fresh mutable object. The magic comment at the very first line freezes all literals in the file instead.
Frozen strings can be shared safely, which trims both allocation count and garbage collector pressure.
# frozen_string_literal: true
name = "Ada"
puts name.frozen?
Avoid garbage
Intermediate arrays and strings cost time twice, once to build and once to collect. Bang methods transform in place and skip the throwaway copy.
Prefer map with a bang over plain map when the original array is no longer needed elsewhere.
names = ["ada", "bob"]
names.map! { |n| n.upcase }
puts names.inspect
Measure first
Optimize the hot path, not a random line. A monotonic clock around the suspect code shows elapsed seconds without wall clock jumps.
When the number refuses to shrink, the bottleneck lives elsewhere, so profile a wider scope before rewriting more code.
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
1000.times { "x" * 10 }
done = Process.clock_gettime(Process::CLOCK_MONOTONIC)
puts(done - start)
Next: Modern Ruby tour
Article author: Arthur Isaev