From 164972eb8be1aa2cabcdc5437663e38e71608cf5 Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Mon, 28 Jul 2014 02:02:29 -0600 Subject: resolves #1021 add preliminary benchmark files to repository --- benchmark/.gitignore | 2 + benchmark/.ruby-gemset | 1 + benchmark/.ruby-version | 1 + benchmark/benchmark.rb | 125 ++++++++++++++ benchmark/sample-data/mdbasics.adoc | 334 ++++++++++++++++++++++++++++++++++++ 5 files changed, 463 insertions(+) create mode 100644 benchmark/.gitignore create mode 100644 benchmark/.ruby-gemset create mode 100644 benchmark/.ruby-version create mode 100644 benchmark/benchmark.rb create mode 100644 benchmark/sample-data/mdbasics.adoc diff --git a/benchmark/.gitignore b/benchmark/.gitignore new file mode 100644 index 00000000..0f4e4641 --- /dev/null +++ b/benchmark/.gitignore @@ -0,0 +1,2 @@ +/sample-data/userguide.adoc +/sample-data/customers.csv diff --git a/benchmark/.ruby-gemset b/benchmark/.ruby-gemset new file mode 100644 index 00000000..71be6191 --- /dev/null +++ b/benchmark/.ruby-gemset @@ -0,0 +1 @@ +asciidoctor-bench diff --git a/benchmark/.ruby-version b/benchmark/.ruby-version new file mode 100644 index 00000000..879b416e --- /dev/null +++ b/benchmark/.ruby-version @@ -0,0 +1 @@ +2.1 diff --git a/benchmark/benchmark.rb b/benchmark/benchmark.rb new file mode 100644 index 00000000..42f3b8f5 --- /dev/null +++ b/benchmark/benchmark.rb @@ -0,0 +1,125 @@ +#!/usr/bin/env ruby + +=begin + +Use this script to monitor changes in performance when making code changes to Asciidoctor. + + $ ruby benchmark.rb + +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=800000 RUBY_GC_HEAP_FREE_SLOTS=800000 RUBY_GC_HEAP_GROWTH_MAX_SLOTS=250000 RUBY_GC_HEAP_GROWTH_FACTOR=1.25 ruby benchmark.rb userguide-loop 10 + +Asciidoctor starts with ~ 12,500 objects, adds ~ 300,000 each run, so tune RUBY_GC_HEAP_* accordingly + +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 = open(userguide_uri) {|fd2| fd2.read } + customers_content = open(customers_uri) {|fd2| fd2.read } + File.open('sample-data/userguide.adoc', 'w') {|fd1| fd1.write userguide_content } + File.open('sample-data/customers.csv', 'w') {|fd1| fd1.write customers_content } +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 + 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 => {'linkcss' => '', 'toc' => nil, 'numbered' => nil, 'icons' => nil, 'compat-mode' => 'legacy'} + } + } + } + # 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 + 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) + + best = nil + 2.times.each do + outer_start = Time.now + (1..$repeat).each do + inner_start = Time.now + Asciidoctor.render_file sample_file, :backend => backend, :safe => Asciidoctor::SafeMode::SAFE, :eruby => 'erubis', :header_footer => true, :to_file => false, :attributes => {'linkcss' => '', 'toc' => nil, 'numbered' => nil, 'icons' => nil, 'compat-mode' => 'legacy'} + puts (elapsed = Time.now - inner_start) + best = (best ? [best, elapsed].min : elapsed) + end + puts %(Run Total: #{Time.now - outer_start}) + end + puts %(Best Time: #{best}) + +when 'mdbasics-loop' + require '../lib/asciidoctor.rb' + GC.start + sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/userguide.adoc' + backend = ENV['BENCH_BACKEND'] || 'html5' + + best = nil + 2.times do + outer_start = Time.now + (1..$repeat).each do + inner_start = Time.now + Asciidoctor.render_file sample_file, :backend => backend, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :to_file => false, :attributes => {'linkcss' => '', 'idprefix' => '', 'idseparator' => '-', 'showtitle' => ''} + puts (elapsed = Time.now - inner_start) + best = (best ? [best, elapsed].min : elapsed) + end + puts %(Run Total: #{Time.now - outer_start}) + end + puts %(Best Time: #{best}) + +end diff --git a/benchmark/sample-data/mdbasics.adoc b/benchmark/sample-data/mdbasics.adoc new file mode 100644 index 00000000..0183ae8d --- /dev/null +++ b/benchmark/sample-data/mdbasics.adoc @@ -0,0 +1,334 @@ +// converted to AsciiDoc from https://github.com/gettalong/kramdown/blob/master/benchmark/mdbasics.text +# Markdown: Basics +John Gruber +:s: link:/projects/markdown/syntax +:d: link:/projects/markdown/dingus +:src: link:/projects/markdown/basics.text + +++++ + +++++ + +## Getting the Gist of Markdown's Formatting Syntax + +This page offers a brief overview of what it's like to use Markdown. +The {s}[syntax page] provides complete, detailed documentation for +every feature, but Markdown should be very easy to pick up simply by +looking at a few examples of it in action. The examples on this page +are written in a before/after style, showing example syntax and the +HTML output produced by Markdown. + +It's also helpful to simply try Markdown out; the {d}[Dingus] is a +web application that allows you type your own Markdown-formatted text +and translate it to XHTML. + +NOTE: This document is itself written using Markdown; you +can {src}[see the source for it by adding \'.text' to the URL]. + +### Paragraphs, Headers, Blockquotes + +A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs. + +Markdown offers two styles of headers: _Setext_ and _atx_. +Setext-style headers for +

+ and +

+ are created by +"underlining" with equal signs (+=+) and hyphens (+-+), respectively. +To create an atx-style header, you put 1-6 hash marks (+#+) at the +beginning of the line -- the number of hashes equals the resulting +HTML header level. + +Blockquotes are indicated using email-style \'+>+' angle brackets. + +.Markdown: +[listing] +.... +A First Level Header +==================== + +A Second Level Header +--------------------- + +Now is the time for all good men to come to +the aid of their country. This is just a +regular paragraph. + +The quick brown fox jumped over the lazy +dog's back. + +### Header 3 + +> This is a blockquote. +> +> This is the second paragraph in the blockquote. +> +> ## This is an H2 in a blockquote +.... + +.Output: +.... +

A First Level Header

+ +

A Second Level Header

+ +

Now is the time for all good men to come to +the aid of their country. This is just a +regular paragraph.

+ +

The quick brown fox jumped over the lazy +dog's back.

+ +

Header 3

+ +
+

This is a blockquote.

+ +

This is the second paragraph in the blockquote.

+ +

This is an H2 in a blockquote

+
+.... + +### Phrase Emphasis + +Markdown uses asterisks and underscores to indicate spans of emphasis. + +.Markdown: +---- +Some of these words *are emphasized*. +Some of these words _are emphasized also_. + +Use two asterisks for **strong emphasis**. +Or, if you prefer, __use two underscores instead__. +---- + +.Output: +.... +

Some of these words are emphasized. +Some of these words are emphasized also.

+ +

Use two asterisks for strong emphasis. +Or, if you prefer, use two underscores instead.

+.... + +### Lists + +Unordered (bulleted) lists use asterisks, pluses, and hyphens (+*+, ++++, and +-+) as list markers. These three markers are +interchangable; this: + +---- +* Candy. +* Gum. +* Booze. +---- + +this: + +---- ++ Candy. ++ Gum. ++ Booze. +---- + +and this: + +---- +- Candy. +- Gum. +- Booze. +---- + +all produce the same output: + +.... +
    +
  • Candy.
  • +
  • Gum.
  • +
  • Booze.
  • +
+.... + +Ordered (numbered) lists use regular numbers, followed by periods, as +list markers: + +---- +1. Red +2. Green +3. Blue +---- + +.Output: +.... +
    +
  1. Red
  2. +
  3. Green
  4. +
  5. Blue
  6. +
+.... + +If you put blank lines between items, you'll get +

+ tags for the +list item text. You can create multi-paragraph list items by indenting +the paragraphs by 4 spaces or 1 tab: + +---- +* A list item. + + With multiple paragraphs. + +* Another item in the list. +---- + +.Output: +.... +

    +
  • A list item.

    +

    With multiple paragraphs.

  • +
  • Another item in the list.

  • +
+.... + +### Links + +Markdown supports two styles for creating links: _inline_ and +_reference_. With both styles, you use square brackets to delimit the +text you want to turn into a link. + +Inline-style links use parentheses immediately after the link text. +For example: + +---- +This is an [example link](http://example.com/). +---- + +.Output: +.... +

This is an +example link.

+.... + +Optionally, you may include a title attribute in the parentheses: + +---- +This is an [example link](http://example.com/ "With a Title"). +---- + +.Output: +.... +

This is an +example link.

+.... + +Reference-style links allow you to refer to your links by names, which +you define elsewhere in your document: + +---- +I get 10 times more traffic from [Google][1] than from +[Yahoo][2] or [MSN][3]. + +[1]: http://google.com/ "Google" +[2]: http://search.yahoo.com/ "Yahoo Search" +[3]: http://search.msn.com/ "MSN Search" +---- + +.Output: +.... +

I get 10 times more traffic from Google than from Yahoo or MSN.

+.... + +The title attribute is optional. Link names may contain letters, +numbers and spaces, but are _not_ case sensitive: + +---- +I start my morning with a cup of coffee and +[The New York Times][NY Times]. + +[ny times]: http://www.nytimes.com/ +---- + +.Output: +.... +

I start my morning with a cup of coffee and +The New York Times.

+.... + +### Images + +Image syntax is very much like link syntax. + +.Inline (titles are optional): +---- +![alt text](/path/to/img.jpg "Title") +---- + +.Reference-style: +---- +![alt text][id] + +[id]: /path/to/img.jpg "Title" +---- + +Both of the above examples produce the same output: + +.... +alt text +.... + +### Code + +In a regular paragraph, you can create code span by wrapping text in +backtick quotes. Any ampersands (+&+) and angle brackets (+<+ or ++>+) will automatically be translated into HTML entities. This makes +it easy to use Markdown to write about HTML example code: + +---- +I strongly recommend against using any `` tags. + +I wish SmartyPants used named entities like `—` +instead of decimal-encoded entites like `—`. +---- + +.Output: +.... +

I strongly recommend against using any +<blink> tags.

+ +

I wish SmartyPants used named entities like +&mdash; instead of decimal-encoded +entites like &#8212;.

+.... + +To specify an entire block of pre-formatted code, indent every line of +the block by 4 spaces or 1 tab. Just like with code spans, +&+, +<+, +and +>+ characters will be escaped automatically. + +.Markdown: +---- +If you want your page to validate under XHTML 1.0 Strict, +you've got to put paragraph tags in your blockquotes: + +
+

For example.

+
+---- + +.Output: +.... +

If you want your page to validate under XHTML 1.0 Strict, +you've got to put paragraph tags in your blockquotes:

+ +
<blockquote>
+    <p>For example.</p>
+</blockquote>
+
+.... -- cgit v1.2.3