Возникли проблемы с поиском среднего времени выполнения блока

В настоящее время я занимаюсь программированием Test First и застрял в проблеме с монитором 06_performance, расположенной по адресу http://testfirst.org/live/learn_ruby/performance_monitor Я обнаружил похожий поток в стеке потока, но до сих пор не понимаю проблему. Я провалил два последних теста, чтобы определить среднее время выполнения нескольких блоков. Мой код до сих пор:

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

Я очень смущен тем, что пытается сделать тест. Пока это то, что я думаю, я должен сделать:

Я полагаю, что задача состоит в том, чтобы определить, сколько времени потребуется определенным блокам. Однако я не совсем уверен, почему этот код работает даже для первых нескольких тестов. А также у меня возникли проблемы с точным знанием того, что возвращает выражение yield. Я был бы очень признателен, если бы кто-нибудь помог мне разобраться с этой проблемой, чтобы я понял ее решение.

1 ответ

Решение

Ваш метод в основном пока хорош, за исключением того, что вам не нужно разветвляться i == 1 от i > 1 - { 1.times { yield } функционально эквивалентно простому вызову yield,

yield ничего не возвращает сам по себе. Это ключевое слово, которое указывает, что блок, данный методу, должен быть вызван, и может необязательно получать переменные, которые, в свою очередь, передаются в блок, например:

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

В случае с тестами, с которыми вы связаны, возвращаемые значения блоков являются совершенно несущественными, так как их интересует только то, сколько времени потребуется для запуска блока. Но, как вы можете видеть в приведенном выше примере, yield ключевое слово может быть встроено в отдельный блок (reverse_each do ... end), что означает, что вы можете оборачиваться другим поведением вокруг него каждый раз, когда вызывается данный блок:

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

В этом случае вы хотите вернуть значения из times do ... end блок, чтобы вы могли усреднить вместе время выполнения данного блока, поэтому вам нужно найти способ сохранить их в массиве, усреднить их вместе и вернуть это среднее значение в результате вашего measure метод. Помните, что вы можете усреднить одно значение, чтобы вернуть это значение, поэтому вам не нужно разное поведение для одиночных и множественных прогонов. Подсказка - вы можете позвонить n.times.map do ... end вернуть массив прямо из times блок, без необходимости создавать его явно.

Другие вопросы по тегам