File: benchmark.rb

package info (click to toggle)
asciidoctor 2.0.26-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,464 kB
  • sloc: ruby: 45,298; sh: 147; xml: 53; javascript: 48; makefile: 26; ml: 1
file content (138 lines) | stat: -rwxr-xr-x 5,460 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env ruby

=begin

Use this script to monitor changes in performance when making code changes to Asciidoctor.

 $ ruby benchmark.rb <benchmark-name> <repeat>

The most common benchmark is the userguide-loop.
It will download the AsciiDoc User Guide automatically the first time, then convert it in memory.
Running it 10 times provides a good picture.

 $ ruby benchmark.rb userguide-loop 10

Only worry about the relative change to the numbers before and after the code change.
Absolute times are highly dependent on the capabilities of the machine the the version of Ruby.

To get the best results under MRI, tune Ruby using environment variables as follows:

.Ruby < 2.1
 $ RUBY_GC_MALLOC_LIMIT=90000000 RUBY_FREE_MIN=650000 ruby benchmark.rb userguide-loop 10

.Ruby >= 2.1
 $ RUBY_GC_MALLOC_LIMIT=128000000 RUBY_GC_OLDMALLOC_LIMIT=128000000 RUBY_GC_HEAP_INIT_SLOTS=10000000 RUBY_GC_HEAP_FREE_SLOTS=10000000 RUBY_GC_HEAP_GROWTH_MAX_SLOTS=250000 RUBY_GC_HEAP_GROWTH_FACTOR=2 ruby benchmark.rb userguide-loop 10
 $ RUBY_GC_MALLOC_LIMIT=128000000 RUBY_GC_OLDMALLOC_LIMIT=128000000 RUBY_GC_HEAP_INIT_SLOTS=20000000 RUBY_GC_HEAP_FREE_SLOTS=1000000 RUBY_GC_HEAP_GROWTH_MAX_SLOTS=250000 RUBY_GC_HEAP_GROWTH_FACTOR=2 ruby benchmark.rb userguide-loop 10

Asciidoctor starts with ~ 12,500 objects, adds ~ 300,000 each run, so tune RUBY_GC_HEAP_* accordingly

See http://globaldev.co.uk/2014/05/ruby-2-1-in-detail/#gc-tuning-environment-variables

Execute Ruby using the `--disable=gems` flag to speed up the initial load time, as shown below:

 $ ruby --disable=gems ...

=end

require 'benchmark'
include Benchmark

bench = ARGV[0]
$repeat = ARGV[1].to_i || 10000

if bench.nil?
  raise 'You must specify a benchmark to run.'
end

def fetch_userguide
  require 'open-uri'
  userguide_uri = 'https://raw.githubusercontent.com/asciidoc/asciidoc/d43faae38c4a8bf366dcba545971da99f2b2d625/doc/asciidoc.txt'
  customers_uri = 'https://raw.githubusercontent.com/asciidoc/asciidoc/d43faae38c4a8bf366dcba545971da99f2b2d625/doc/customers.csv'
  userguide_content = OpenURI.open_uri(userguide_uri) {|fd2| fd2.read }
  customers_content = OpenURI.open_uri(customers_uri) {|fd2| fd2.read }
  File.write 'sample-data/userguide.adoc', userguide_content, mode: 'w:utf-8'
  File.write 'sample-data/customers.csv', customers_content, mode: 'w:utf-8'
end

case bench

=begin
# benchmark template

when 'name'

  sample = 'value'

  Benchmark.bmbm(12) {|bm|
    bm.report('operation a') { $repeat.times { call_a_on sample } }
    bm.report('operation b') { $repeat.times { call_b_on sample } }
  }
=end

when 'userguide'
  require '../lib/asciidoctor.rb'
  Asciidoctor::Compliance.markdown_syntax = false
  Asciidoctor::Compliance.shorthand_property_syntax = false if Asciidoctor::VERSION > '0.1.4'
  sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/userguide.adoc'
  backend = ENV['BENCH_BACKEND'] || 'html5'
  fetch_userguide if sample_file == 'sample-data/userguide.adoc' && !(File.exist? sample_file)
  result = Benchmark.bmbm {|bm|
    bm.report(%(Convert #{sample_file} (x#{$repeat}))) {
      $repeat.times {
        Asciidoctor.render_file sample_file, :backend => backend, :safe => Asciidoctor::SafeMode::SAFE, :eruby => 'erubis', :header_footer => true, :to_file => false, :attributes => {'stylesheet' => nil, 'toc' => nil, 'numbered' => nil, 'icons' => nil, 'compat-mode' => ''}
      }
    }
  }
  # prints average for real run
  puts %(>avg: #{result.first.real / $repeat})

when 'userguide-loop'
  require '../lib/asciidoctor.rb'
  GC.start
  Asciidoctor::Compliance.markdown_syntax = false
  Asciidoctor::Compliance.shorthand_property_syntax = false if Asciidoctor::VERSION > '0.1.4'
  sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/userguide.adoc'
  backend = ENV['BENCH_BACKEND'] || 'html5'
  fetch_userguide if sample_file == 'sample-data/userguide.adoc' && !(File.exist? sample_file)

  timings = []
  2.times.each do
    loop_timings = []
    (1..$repeat).each do
      start = Time.now
      Asciidoctor.render_file sample_file, :backend => backend, :safe => Asciidoctor::SafeMode::SAFE, :eruby => 'erubis', :header_footer => true, :to_file => false, :attributes => { 'stylesheet' => nil, 'toc' => nil, 'numbered' => nil, 'icons' => nil, 'compat-mode' => '' }
      loop_timings << (Time.now - start)
    end
    timings << loop_timings
  end
  best_time = nil
  timings.each do |loop_timings|
    puts %(#{loop_timings * "\n"}\nRun Total: #{loop_timings.reduce :+})
    best_time = best_time ? [best_time, loop_timings.min].min : loop_timings.min
  end
  puts %(Best Time: #{best_time})

when 'mdbasics-loop'
  require '../lib/asciidoctor.rb'
  GC.start
  sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/mdbasics.adoc'
  backend = ENV['BENCH_BACKEND'] || 'html5'

  timings = []
  2.times do
    loop_timings = []
    (1..$repeat).each do
      start = Time.now
      Asciidoctor.render_file sample_file, :backend => backend, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :to_file => false, :attributes => { 'stylesheet' => nil, 'idprefix' => '', 'idseparator' => '-', 'showtitle' => '' }
      loop_timings << (Time.now - start)
    end
    timings << loop_timings
  end
  best_time = nil
  timings.each do |loop_timings|
    puts %(#{loop_timings * "\n"}\nRun Total: #{loop_timings.reduce :+})
    best_time = best_time ? [best_time, loop_timings.min].min : loop_timings.min
  end
  puts %(Best Time: #{best_time})

end