Class: Fruity::ComparisonRun

Inherits:
Struct
  • Object
show all
Defined in:
lib/fruity/comparison_run.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group, timings, baselines) ⇒ ComparisonRun

timings must be an array of size ‘group.size` of arrays of delays or of arrays of [delay, baseline]

Raises:

  • (ArgumentError)


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/fruity/comparison_run.rb', line 10

def initialize(group, timings, baselines)
  raise ArgumentError, "Expected timings to be an array with #{group.size} elements (was #{timings.size})" unless timings.size == group.size
  super

  filter = group.options.fetch(:filter)

  baseline = Util.filter(baselines, *filter) if baseline_type == :single

  @stats = timings.map.with_index do |series, i|
    case baseline_type
    when :split
      Util.difference(Util.filter(series, *filter), Util.filter(baselines.fetch(i), *filter))
    when :single
      Util.difference(Util.filter(series, *filter), baseline)
    when :none
      Util.stats(series)
    end
  end.freeze
end

Instance Attribute Details

#baselinesObject

Returns the value of attribute baselines

Returns:

  • (Object)

    the current value of baselines



4
5
6
# File 'lib/fruity/comparison_run.rb', line 4

def baselines
  @baselines
end

#groupObject

Returns the value of attribute group

Returns:

  • (Object)

    the current value of group



4
5
6
# File 'lib/fruity/comparison_run.rb', line 4

def group
  @group
end

#statsObject (readonly)

Returns the value of attribute stats.



5
6
7
# File 'lib/fruity/comparison_run.rb', line 5

def stats
  @stats
end

#timingsObject

Returns the value of attribute timings

Returns:

  • (Object)

    the current value of timings



4
5
6
# File 'lib/fruity/comparison_run.rb', line 4

def timings
  @timings
end

Instance Method Details

#baseline_typeObject



95
96
97
98
99
100
101
102
103
# File 'lib/fruity/comparison_run.rb', line 95

def baseline_type
  if baselines.nil?
    :none
  elsif baselines.first.is_a?(Array)
    :split
  else
    :single
  end
end

#comparison(cur = 0, vs = 1) ⇒ Object



81
82
83
# File 'lib/fruity/comparison_run.rb', line 81

def comparison(cur = 0, vs = 1)
  Util.compare_stats(@stats[cur], @stats[vs])
end

#export(fn = (require "tmpdir"; "#{Dir.tmpdir}/export.csv")) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/fruity/comparison_run.rb', line 49

def export(fn = (require "tmpdir"; "#{Dir.tmpdir}/export.csv"))
  require "csv"
  CSV.open(fn, "wb") do |csv|
    head = group.elements.keys
    case baseline_type
    when :split
      head = head.flat_map{|h| [h, "#{head} bl"]}
      data = timings.zip(baselines).flatten(1).transpose
    when :single
      data = (timings + [baselines]).transpose
      head << "baseline"
    else
      data = timings.transpose
    end
    csv << head
    data.each{|vals| csv << vals}
  end
  fn
end

#factor(cur = 0, vs = 1) ⇒ Object



73
74
75
# File 'lib/fruity/comparison_run.rb', line 73

def factor(cur = 0, vs = 1)
  comparison(cur, vs)[:factor]
end

#factor_range(cur = 0, vs = 1) ⇒ Object



77
78
79
# File 'lib/fruity/comparison_run.rb', line 77

def factor_range(cur = 0, vs =1)
  comparison(cur, vs)[:min]..comparison(cur, vs)[:max]
end

#format_comparison(cmp) ⇒ Object



85
86
87
88
89
90
91
92
93
# File 'lib/fruity/comparison_run.rb', line 85

def format_comparison(cmp)
  ratio = cmp[:factor]
  prec = cmp[:precision]
  if ratio.abs > 1.8
    "#{ratio}x ± #{prec}"
  else
    "#{(ratio - 1)*100}% ± #{prec*100}%"
  end
end

#sizeObject



69
70
71
# File 'lib/fruity/comparison_run.rb', line 69

def size
  timings.first.size
end

#to_sObject



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/fruity/comparison_run.rb', line 30

def to_s
  order = (0...group.size).sort_by{|i| @stats[i][:mean] }
  results = group.elements.map{|n, exec| Util.result_of(exec, group.options) }
  order.each_cons(2).map do |i, j|
    cmp = comparison(i, j)
    s = if cmp[:factor] == 1
      "%{cur} is similar to %{vs}%{different}"
    else
      "%{cur} is faster than %{vs} by %{ratio}%{different}"
    end
    s % {
      :cur => group.elements.keys[i],
      :vs => group.elements.keys[j],
      :ratio => format_comparison(cmp),
      :different => results[i] == results[j] ? "" : " (results differ: #{results[i]} vs #{results[j]})"
    }
  end.join("\n")
end