Added version 0.5-rc1

Change-Id: Ic21eda3c659eadf3a4229ae5618e9ce1e96b4aa7
diff --git a/tutorial/Tutorial.java b/tutorial/Tutorial.java
new file mode 100644
index 0000000..625d387
--- /dev/null
+++ b/tutorial/Tutorial.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tutorial;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * Caliper tutorial. To run the example benchmarks in this file:
+ * {@code CLASSPATH=... [caliper_home]/caliper tutorial.Tutorial.Benchmark1}
+ */
+public class Tutorial {
+
+  /*
+   * We begin the Caliper tutorial with the simplest benchmark you can write.
+   * We'd like to know how efficient the method System.nanoTime() is.
+   *
+   * Notice:
+   *
+   *  - We write a class that extends com.google.caliper.SimpleBenchmark.
+   *  - It contains a public instance method whose name begins with 'time' and
+   *    which accepts a single 'int reps' parameter.
+   *  - The body of the method simply executes the code we wish to measure,
+   *    'reps' times.
+   *
+   * Example run:
+   *
+   *    $ CLASSPATH=build/classes/test caliper tutorial.Tutorial.Benchmark1
+   *    [real-time results appear on this line]
+   *
+   *    Summary report for tutorial.Tutorial$Benchmark1:
+   *
+   *    Benchmark   ns
+   *    ---------  ---
+   *    NanoTime   233
+   */
+  public static class Benchmark1 extends SimpleBenchmark {
+    public void timeNanoTime(int reps) {
+      for (int i = 0; i < reps; i++) {
+        System.nanoTime();
+      }
+    }
+  }
+
+  /*
+   * Now let's compare two things: nanoTime() versus currentTimeMillis().
+   * Notice:
+   *
+   *  - We simply add another method, following the same rules as the first.
+   *
+   * Example run output:
+   *
+   *   Benchmark           ns
+   *   -----------------  ---
+   *   NanoTime           248
+   *   CurrentTimeMillis  118
+   */
+  public static class Benchmark2 extends SimpleBenchmark {
+    public void timeNanoTime(int reps) {
+      for (int i = 0; i < reps; i++) {
+        System.nanoTime();
+      }
+    }
+    public void timeCurrentTimeMillis(int reps) {
+      for (int i = 0; i < reps; i++) {
+        System.currentTimeMillis();
+      }
+    }
+  }
+
+  /*
+   * Let's try iterating over a large array. This seems simple enough, but
+   * there is a problem!
+   */
+  public static class Benchmark3 extends SimpleBenchmark {
+    private final int[] array = new int[1000000];
+
+    @SuppressWarnings("UnusedDeclaration") // IDEA tries to warn us!
+    public void timeArrayIteration_BAD(int reps) {
+      for (int i = 0; i < reps; i++) {
+        for (int ignoreMe : array) {}
+      }
+    }
+  }
+
+  /*
+   * Caliper reported that the benchmark above ran in 4 nanoseconds.
+   *
+   * Wait, what?
+   *
+   * How can it possibly iterate over a million zeroes in 4 ns!?
+   *
+   * It is very important to sanity-check benchmark results with common sense!
+   * In this case, we're indeed getting a bogus result. The problem is that the
+   * Java Virtual Machine is too smart: it detected the fact that the loop was
+   * producing no actual result, so it simply compiled it right out. The method
+   * never looped at all. To fix this, we need to use a dummy result value.
+   *
+   * Notice:
+   *
+   *  - We simply change the 'time' method from 'void' to any return type we
+   *    wish. Then we return a value that can't be known without actually
+   *    performing the work, and thus we defeat the runtime optimizations.
+   *  - We're no longer timing *just* the code we want to be testing - our
+   *    result will now be inflated by the (small) cost of addition. This is an
+   *    unfortunate fact of life with microbenchmarking. In fact, we were
+   *    already inflated by the cost of an int comparison, "i < reps" as it was.
+   *
+   * With this change, Caliper should report a much more realistic value, more
+   * on the order of an entire millisecond.
+   */
+  public static class Benchmark4 extends SimpleBenchmark {
+    private final int[] array = new int[1000000];
+
+    public int timeArrayIteration_fixed(int reps) {
+      int dummy = 0;
+      for (int i = 0; i < reps; i++) {
+        for (int doNotIgnoreMe : array) {
+          dummy += doNotIgnoreMe;
+        }
+      }
+      return dummy; // framework ignores this, but it has served its purpose!
+    }
+  }
+
+  /*
+   * Now we'd like to know how various other *sizes* of arrays perform. We
+   * don't want to have to cut and paste the whole benchmark just to provide a
+   * different size. What we need is a parameter!
+   *
+   * When you run this benchmark the same way you ran the previous ones, you'll
+   * now get an error: "No values provided for benchmark parameter 'size'".
+   * You can provide the value requested at the command line like this:
+   *
+   *   [caliper_home]/caliper tutorial.Tutorial.Benchmark5 -Dsize=100}
+   *
+   * You'll see output like this:
+   *
+   *   Benchmark       size   ns
+   *   --------------  ----  ---
+   *   ArrayIteration   100   51
+   *
+   * Now that we've parameterized our benchmark, things are starting to get fun.
+   * Try passing '-Dsize=10,100,1000' and see what happens!
+   *
+   *   Benchmark       size   ns
+   *   --------------  ----  -----------------------------------
+   *   ArrayIteration    10    7 |
+   *   ArrayIteration   100   49 ||||
+   *   ArrayIteration  1000  477 ||||||||||||||||||||||||||||||
+   *
+   */
+  public static class Benchmark5 extends SimpleBenchmark {
+    @Param int size; // set automatically by framework
+
+    private int[] array; // set by us, in setUp()
+
+    @Override protected void setUp() {
+      // @Param values are guaranteed to have been injected by now
+      array = new int[size];
+    }
+
+    public int timeArrayIteration(int reps) {
+      int dummy = 0;
+      for (int i = 0; i < reps; i++) {
+        for (int doNotIgnoreMe : array) {
+          dummy += doNotIgnoreMe;
+        }
+      }
+      return dummy;
+    }
+  }
+}