Возникли проблемы с поиском среднего времени выполнения блока
В настоящее время я занимаюсь программированием 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
блок, без необходимости создавать его явно.