Существует много способов сделать это, ваш - одно решение, и мне кажется, что это хорошо. Если реализованы два дополнительных решения и контрольный показатель. Ваше решение было самым быстрым из этих трех (заявление об отказе от microbenchmark применяется, особенно потому, что я делаю IO с puts
/print
).
def staircase_0(size)
string = ' ' * (size - 1) + '#' * size
size.times do |offset|
puts string[offset...(offset + size)]
end
end
def staircase_1(size)
prefix = ' ' * (size - 1)
postfix = '#'
size.times do
print prefix
puts postfix
prefix = prefix[1..-1]
postfix += '#'
end
end
def staircase_2(num_rows)
for i in (1..num_rows)
puts ' ' * (num_rows-i) + '#' * i
end
end
require 'benchmark/ips'
Benchmark.ips do |x|
x.report('_0') do
staircase_0(6)
end
x.report('_1') do
staircase_1(6)
end
x.report('_2') do
staircase_2(6)
end
x.compare!
end
И результаты:
Comparison:
_2: 35649.0 i/s
_0: 29716.3 i/s - 1.20x slower
_1: 25848.2 i/s - 1.38x slower
Помните, что в связи с IO результаты могут сильно отличаться. IO медленный (поэтому он имеет больше веса, чем ваш алгоритм и конкатенация строк). Он также не предсказуем и может отличаться от прогона до бега. Поэтому более эффективным (с точки зрения выполнения) решение может быть выходом только одна строка:
def staircase_3(size)
string = ''
size.times do |index|
string += ' ' * (size - index - 1) + '#' * (index + 1) + "\n"
end
puts string
end
И действительно, когда я запускать тесты это быстрее:
Comparison:
_3: 52923.7 i/s
_0: 36377.7 i/s - 1.45x slower
_2: 33508.7 i/s - 1.58x slower
_1: 25991.6 i/s - 2.04x slower
отметить также, что в этом пробеге ваша версия алгоритма (staircase_2
) медленнее, чем staircase_0
... что связано с IO. Но во всех моих прогонах staircase_3
был самым быстрым.
Почему вы думаете, что это хак? –
@JanDvorak Извините, я имею в виду неэффективность, проверьте мое обновление! –
Я не думаю, что это неэффективно. Кроме того, в этом случае вам не нужна производительность. –