require 'benchmark'

module Variance
  def sum(&blk)
    if block_given?
      map(&blk).sum
    else
      inject { |sum, element| sum + element }
    end
  end

  def mean
    (sum.to_f / size.to_f)
  end

  def variance
    m = mean
    sum { |i| ( i - m )**2 } / size
  end
end

class Array
  include Variance
end

def generate_array
  Benchmark.bm(20) do |x|
    x.report("Generate array") do
      @ary = ([1] * 10**6).map {|i| rand}
    end
  end
  @ary
end

ary = generate_array

Benchmark.bm(20) do |x|
  x.report("Sergio's variance") { ary.variance }
  x.report("Tim's variance") do
    mean = (ary.inject(0.0) {|s,x| s + x}) / Float(ary.length)
    variance = ary.inject(0.0) {|s,x| s + (x - mean)**2}
  end
end