I have a benchmark like follows:
benchmark_result = Benchmark.bm do |x|
x.report { send(test_name) }
end
When I run this, I'm seeing output from two places:
- The
send(test_name)
in the report
block. I want to continue seeing this output.
- The output from the Benchmark block, i.e. the resulting benchmark report is printed to the console. I don't want this to happen.
I've seen from here how to temporarily hide the console output. But the problem is that I want the inner block to continue printing its output. I just don't want to see the benchmark results.
When you call the report
method on the Benchmark::Report
object sent to the block by Benchmark.bm
or Benchmark.benchmark
, it will print to STDOUT. If you're just interested in the benchmark metrics without printing a report, you can do this:
benchmark_result = Benchmark.measure do
send(test_name)
end
It returns a Benchmark::Tms
object that looks like this:
=> #<Benchmark::Tms:0x007fb5b1b40118
@cstime=0.0,
@cutime=0.0,
@label="",
@real=4.5693013817071915e-05,
@stime=0.0,
@total=0.0,
@utime=0.0>
If you're just interested in the elapsed real time used to execute your block, do the following (returns a Float
):
benchmark_result = Benchmark.realtime do
send(test_name)
end
I've accepted Amit's answer because it seems canonical, but I did figure out another way to do it in the meantime.
From this question I have added the following code (slightly modified to include the touch/rm
calls on the null.txt
file):
def silence_output
# Store the original stderr and stdout in order to restore them later
@original_stderr = $stderr
@original_stdout = $stdout
# Redirect stderr and stdout
`touch null.txt`
$stderr = File.new(File.join(File.dirname(__FILE__), 'null.txt'), 'w')
$stdout = File.new(File.join(File.dirname(__FILE__), 'null.txt'), 'w')
end
# Replace stderr and stdout so anything else is output correctly
def enable_output
$stderr = @original_stderr
$stdout = @original_stdout
@original_stderr = nil
@original_stdout = nil
`rm null.txt`
end
With this, I can accomplish my goal using the following:
silence_output
benchmark_result = Benchmark.bm do |x|
x.report do
enable_output
send(test_name)
silence_output
end
end
enable_output
Although after seeing a better way to do it, this seems very hacky.