Ruby: Proc#call по сравнению с урожаем

Следующий запрос заменяет каждый a символ с b символ.

UPDATE 
    YourTable
SET 
    Column1 = REPLACE(Column1,'a','b')
WHERE 
    Column1 LIKE '%a%'

Это не будет работать над SQL-сервером 2003.

75
задан Mohsen Nosratinia 8 May 2015 в 14:11
поделиться

2 ответа

Я думаю, что первое на самом деле является синтаксическим сахаром другого. Другими словами, нет никакой разницы в поведении.

Однако вторая форма позволяет «сохранять» блок в переменной. Затем блок может быть вызван в какой-то другой момент времени - обратный вызов.


Хорошо. На этот раз я сделал быстрый тест:

require 'benchmark'

class A
  def test
    10.times do
      yield
    end
  end
end

class B
  def test(&block)
    10.times do
      block.call
    end
  end
end

Benchmark.bm do |b|
  b.report do
    a = A.new
    10000.times do
      a.test{ 1 + 1 }
    end
  end

  b.report do
    a = B.new
    10000.times do
      a.test{ 1 + 1 }
    end
  end

  b.report do
    a = A.new
    100000.times do
      a.test{ 1 + 1 }
    end
  end

  b.report do
    a = B.new
    100000.times do
      a.test{ 1 + 1 }
    end
  end

end

Результаты интересны:

      user     system      total        real
  0.090000   0.040000   0.130000 (  0.141529)
  0.180000   0.060000   0.240000 (  0.234289)
  0.950000   0.370000   1.320000 (  1.359902)
  1.810000   0.570000   2.380000 (  2.430991)

Это показывает, что использование block.call почти в 2 раза медленнее, чем использование yield .

]
51
ответ дан 24 November 2019 в 11:43
поделиться

Они выдают разные сообщения об ошибках, если вы забыли передать блок:

> WithYield::thrice
LocalJumpError: no block given
        from (irb):3:in `thrice'
        from (irb):3:in `times'
        from (irb):3:in `thrice'

> WithProcCall::thrice
NoMethodError: undefined method `call' for nil:NilClass
        from (irb):9:in `thrice'
        from (irb):9:in `times'
        from (irb):9:in `thrice'

Но они ведут себя так же, если вы пытаетесь передать «нормальный» (неблочный) аргумент:

> WithYield::thrice(42)
ArgumentError: wrong number of arguments (1 for 0)
        from (irb):19:in `thrice'

> WithProcCall::thrice(42)
ArgumentError: wrong number of arguments (1 for 0)
        from (irb):20:in `thrice'
6
ответ дан 24 November 2019 в 11:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: