Domanda

I am currently doing Test First programming and am stuck on the 06_performance monitor problem located at http://testfirst.org/live/learn_ruby/performance_monitor I found a similar thread on stackoverflow but I still am not understanding the problem. I am failing the last two tests on finding the average run time of multiple blocks. My code so far is:

def measure(i=1)
  if i>1
    i.times do 
      yield
    end
  else
    x = Time.now
    yield
    elapsed_time = Time.now - x
  end
end

I am very confused at what the test is trying to do. So far this is what I think I have to do:

I believe the task is to find how long certain blocks take to run. However, I am not sure exactly why this code is even working for the first few tests. And also I am having issues with knowing exactly what the yield statement is returning. I would really appreciate it if someone could walk me through the process of solving this problem so that I understand the solution.

È stato utile?

Soluzione

Your method is mostly ok so far, except you don't need to branch out i == 1 from i > 1{ 1.times { yield } is functionally equivalent to just calling yield.

yield doesn't return anything on its own. It is a keyword that indicates the block given to the method should be called, and can optionally be fed variables that would in turn get passed to the block, e.g:

class String
  def each_character_in_reverse_order
    each_char.to_a.reverse_each do |char|
      yield char
    end
  end
end

"hello".each_character_in_reverse_order do |c|
  puts c.upcase
end

#=> 
# O
# L
# L
# E
# H

In the case of the tests you've linked to, the return values of the blocks are complete inconsequential, as they are only interested in how long it takes to run the block. But as you can see in the example above, the yield keyword can be embedded in a block of its own (reverse_each do ... end), which means you can wrap other behavior around it each time the given block is called:

1.times do
  start_time = Time.now
  yield
  elapsed = Time.now - start_time
end

In this case, you want to return values from the times do ... end block so you can average together the runtimes of the given block, so you need to find a way to store these in an array, average them together, and return that average as the result of your measure method. Keep in mind that you can average a single value to return that value, so you don't need different behavior for single runs vs. multiple runs. Hint - you can call n.times.map do ... end to return an array directly from the times block, without having to instantiate one explicitly.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top