Ruby: Proc#call vs yield

后端 未结 6 1476
野性不改
野性不改 2020-12-02 05:54

What are the behavioural differences between the following two implementations in Ruby of the thrice method?

module WithYield
  def self.thrice
         


        
6条回答
  •  时光说笑
    2020-12-02 06:35

    I think the first one is actually a syntactic sugar of the other. In other words there is no behavioural difference.

    What the second form allows though is to "save" the block in a variable. Then the block can be called at some other point in time - callback.


    Ok. This time I went and did a quick benchmark:

    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
    

    The results are interesting:

          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)
    

    This shows that using block.call is almost 2x slower than using yield.

提交回复
热议问题