Commits

Anonymous committed 97aba27

Add the code.google.com/p/dalvik benchmarks to libcore.

I'll remove them from code.google.com afterwards.

Change-Id: I369a301ed0e116c7971caebc607c5a86d06d4ee2

Comments (0)

Files changed (70)

benchmarks/AdditionBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * What do various kinds of addition cost?
+ */
+public class AdditionBenchmark extends SimpleBenchmark {
+    public int timeAddConstantToLocalInt(int reps) {
+        int result = 0;
+        for (int i = 0; i < reps; ++i) {
+            result += 123;
+        }
+        return result;
+    }
+    public int timeAddTwoLocalInts(int reps) {
+        int result = 0;
+        int constant = 123;
+        for (int i = 0; i < reps; ++i) {
+            result += constant;
+        }
+        return result;
+    }
+    public long timeAddConstantToLocalLong(int reps) {
+        long result = 0;
+        for (int i = 0; i < reps; ++i) {
+            result += 123L;
+        }
+        return result;
+    }
+    public long timeAddTwoLocalLongs(int reps) {
+        long result = 0;
+        long constant = 123L;
+        for (int i = 0; i < reps; ++i) {
+            result += constant;
+        }
+        return result;
+    }
+    public float timeAddConstantToLocalFloat(int reps) {
+        float result = 0.0f;
+        for (int i = 0; i < reps; ++i) {
+            result += 123.0f;
+        }
+        return result;
+    }
+    public float timeAddTwoLocalFloats(int reps) {
+        float result = 0.0f;
+        float constant = 123.0f;
+        for (int i = 0; i < reps; ++i) {
+            result += constant;
+        }
+        return result;
+    }
+    public double timeAddConstantToLocalDouble(int reps) {
+        double result = 0.0;
+        for (int i = 0; i < reps; ++i) {
+            result += 123.0;
+        }
+        return result;
+    }
+    public double timeAddTwoLocalDoubles(int reps) {
+        double result = 0.0;
+        double constant = 123.0;
+        for (int i = 0; i < reps; ++i) {
+            result += constant;
+        }
+        return result;
+    }
+}

benchmarks/ArrayCopyBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import java.util.Arrays;
+
+public class ArrayCopyBenchmark extends SimpleBenchmark {
+    public void timeManualArrayCopy(int reps) {
+        char[] src = new char[8192];
+        for (int rep = 0; rep < reps; ++rep) {
+            char[] dst = new char[8192];
+            for (int i = 0; i < 8192; ++i) {
+                dst[i] = src[i];
+            }
+        }
+    }
+
+    public void time_System_arrayCopy(int reps) {
+        char[] src = new char[8192];
+        for (int rep = 0; rep < reps; ++rep) {
+            char[] dst = new char[8192];
+            System.arraycopy(src, 0, dst, 0, 8192);
+        }
+    }
+
+    public void time_Arrays_copyOf(int reps) {
+        char[] src = new char[8192];
+        for (int rep = 0; rep < reps; ++rep) {
+            char[] dst = Arrays.copyOf(src, 8192);
+        }
+    }
+
+    public void time_Arrays_copyOfRange(int reps) {
+        char[] src = new char[8192];
+        for (int rep = 0; rep < reps; ++rep) {
+            char[] dst = Arrays.copyOfRange(src, 0, 8192);
+        }
+    }
+}

benchmarks/ArrayIterationBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * How do various ways of iterating through an array compare?
+ */
+public class ArrayIterationBenchmark extends SimpleBenchmark {
+    Foo[] mArray = new Foo[27];
+    {
+        for (int i = 0; i < mArray.length; ++i) mArray[i] = new Foo();
+    }
+    public void timeArrayIteration(int reps) {
+        for (int rep = 0; rep < reps; ++rep) {
+            int sum = 0;
+            for (int i = 0; i < mArray.length; i++) {
+                sum += mArray[i].mSplat;
+            }
+        }
+    }
+    public void timeArrayIterationCached(int reps) {
+        for (int rep = 0; rep < reps; ++rep) {
+            int sum = 0;
+            Foo[] localArray = mArray;
+            int len = localArray.length;
+            
+            for (int i = 0; i < len; i++) {
+                sum += localArray[i].mSplat;
+            }
+        }
+    }
+    public void timeArrayIterationForEach(int reps) {
+        for (int rep = 0; rep < reps; ++rep) {
+            int sum = 0;
+            for (Foo a: mArray) {
+                sum += a.mSplat;
+            }
+        }
+    }
+}

benchmarks/ArrayListIterationBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import java.util.ArrayList;
+
+/**
+ * Is a hand-coded counted loop through an ArrayList cheaper than enhanced for?
+ */
+public class ArrayListIterationBenchmark extends SimpleBenchmark {
+    ArrayList<Foo> mList = new ArrayList<Foo>();
+    {
+        for (int i = 0; i < 27; ++i) mList.add(new Foo());
+    }
+    public void timeArrayListIterationIndexed(int reps) {
+        for (int rep = 0; rep < reps; ++rep) {
+            int sum = 0;
+            ArrayList<Foo> list = mList;
+            int len = list.size();
+            for (int i = 0; i < len; ++i) {
+                sum += list.get(i).mSplat;
+            }
+        }
+    }
+    public void timeArrayListIterationForEach(int reps) {
+        for (int rep = 0; rep < reps; ++rep) {
+            int sum = 0;
+            for (Foo a : mList) {
+                sum += a.mSplat;
+            }
+        }
+    }
+}

benchmarks/BufferedZipFileBenchmark.java

+/*
+ * Copyright (C) 2011 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.Random;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+public final class BufferedZipFileBenchmark extends SimpleBenchmark {
+    @Param({"128", "1024", "8192", "65536"}) int compressedSize;
+    @Param({"4", "32", "128"}) int readSize;
+
+    private File file;
+
+    @Override protected void setUp() throws Exception {
+        file = File.createTempFile(getClass().getName(), ".zip");
+        file.deleteOnExit();
+
+        Random random = new Random(0);
+        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file));
+        byte[] data = new byte[8192];
+        out.putNextEntry(new ZipEntry("entry.data"));
+        int written = 0;
+        while (written < compressedSize) {
+            random.nextBytes(data);
+            int toWrite = Math.min(compressedSize - written, data.length);
+            out.write(data, 0, toWrite);
+            written += toWrite;
+        }
+        out.close();
+    }
+
+    public void timeUnbufferedRead(int reps) throws Exception {
+        for (int i = 0; i < reps; i++) {
+            ZipFile zipFile = new ZipFile(file);
+            ZipEntry entry = zipFile.getEntry("entry.data");
+            InputStream in = zipFile.getInputStream(entry);
+            byte[] buffer = new byte[readSize];
+            while (in.read(buffer) != -1) {
+            }
+            in.close();
+            zipFile.close();
+        }
+    }
+
+    public void timeBufferedRead(int reps) throws Exception {
+        for (int i = 0; i < reps; i++) {
+            ZipFile zipFile = new ZipFile(file);
+            ZipEntry entry = zipFile.getEntry("entry.data");
+            InputStream in = new BufferedInputStream(zipFile.getInputStream(entry));
+            byte[] buffer = new byte[readSize];
+            while (in.read(buffer) != -1) {
+            }
+            in.close();
+            zipFile.close();
+        }
+    }
+}

benchmarks/FieldAccessBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * What does field access cost?
+ */
+public class FieldAccessBenchmark extends SimpleBenchmark {
+    private static class Inner {
+        public int publicInnerIntVal;
+        protected int protectedInnerIntVal;
+        private int privateInnerIntVal;
+        int packageInnerIntVal;
+    }
+    int intVal = 42;
+    final int finalIntVal = 42;
+    static int staticIntVal = 42;
+    static final int staticFinalIntVal = 42;
+    public int timeField(int reps) {
+        int result = 0;
+        for (int rep = 0; rep < reps; ++rep) {
+            result = intVal;
+        }
+        return result;
+    }
+    public int timeFieldFinal(int reps) {
+        int result = 0;
+        for (int rep = 0; rep < reps; ++rep) {
+            result = finalIntVal;
+        }
+        return result;
+    }
+    public int timeFieldStatic(int reps) {
+        int result = 0;
+        for (int rep = 0; rep < reps; ++rep) {
+            result = staticIntVal;
+        }
+        return result;
+    }
+    public int timeFieldStaticFinal(int reps) {
+        int result = 0;
+        for (int rep = 0; rep < reps; ++rep) {
+            result = staticFinalIntVal;
+        }
+        return result;
+    }
+    public int timeFieldCached(int reps) {
+        int result = 0;
+        int cachedIntVal = this.intVal;
+        for (int rep = 0; rep < reps; ++rep) {
+            result = cachedIntVal;
+        }
+        return result;
+    }
+    public int timeFieldPrivateInnerClassPublicField(int reps) {
+        int result = 0;
+        Inner inner = new Inner();
+        for (int rep = 0; rep < reps; ++rep) {
+            result = inner.publicInnerIntVal;
+        }
+        return result;
+    }
+    public int timeFieldPrivateInnerClassProtectedField(int reps) {
+        int result = 0;
+        Inner inner = new Inner();
+        for (int rep = 0; rep < reps; ++rep) {
+            result = inner.protectedInnerIntVal;
+        }
+        return result;
+    }
+    public int timeFieldPrivateInnerClassPrivateField(int reps) {
+        int result = 0;
+        Inner inner = new Inner();
+        for (int rep = 0; rep < reps; ++rep) {
+            result = inner.privateInnerIntVal;
+        }
+        return result;
+    }
+    public int timeFieldPrivateInnerClassPackageField(int reps) {
+        int result = 0;
+        Inner inner = new Inner();
+        for (int rep = 0; rep < reps; ++rep) {
+            result = inner.packageInnerIntVal;
+        }
+        return result;
+    }
+}

benchmarks/Foo.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+/**
+ * A trivial class used by several benchmarks.
+ */
+public class Foo {
+    int mSplat;
+}

benchmarks/HashedCollectionsBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
+
+/**
+ * How do the various hash maps compare?
+ */
+public class HashedCollectionsBenchmark extends SimpleBenchmark {
+    public void timeHashMapGet(int reps) {
+        HashMap<String, String> map = new HashMap<String, String>();
+        map.put("hello", "world");
+        for (int i = 0; i < reps; ++i) {
+            map.get("hello");
+        }
+    }
+    public void timeHashMapGet_Synchronized(int reps) {
+        HashMap<String, String> map = new HashMap<String, String>();
+        synchronized (map) {
+            map.put("hello", "world");
+        }
+        for (int i = 0; i < reps; ++i) {
+            synchronized (map) {
+                map.get("hello");
+            }
+        }
+    }
+    public void timeHashtableGet(int reps) {
+        Hashtable<String, String> map = new Hashtable<String, String>();
+        map.put("hello", "world");
+        for (int i = 0; i < reps; ++i) {
+            map.get("hello");
+        }
+    }
+    public void timeLinkedHashMapGet(int reps) {
+        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
+        map.put("hello", "world");
+        for (int i = 0; i < reps; ++i) {
+            map.get("hello");
+        }
+    }
+    public void timeConcurrentHashMapGet(int reps) {
+        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>();
+        map.put("hello", "world");
+        for (int i = 0; i < reps; ++i) {
+            map.get("hello");
+        }
+    }
+}

benchmarks/MethodInvocationBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * Compares various kinds of method invocation.
+ */
+public class MethodInvocationBenchmark extends SimpleBenchmark {
+    interface I {
+        void emptyInterface();
+    }
+
+    static class C implements I {
+        private int field;
+
+        private int getField() {
+            return field;
+        }
+
+        public int timeInternalGetter(int reps) {
+            int result = 0;
+            for (int i = 0; i < reps; ++i) {
+                result = getField();
+            }
+            return result;
+        }
+
+        public int timeInternalFieldAccess(int reps) {
+            int result = 0;
+            for (int i = 0; i < reps; ++i) {
+                result = field;
+            }
+            return result;
+        }
+
+        public static void emptyStatic() {
+        }
+
+        public void emptyVirtual() {
+        }
+
+        public void emptyInterface() {
+        }
+    }
+
+    public void timeInternalGetter(int reps) {
+        new C().timeInternalGetter(reps);
+    }
+
+    public void timeInternalFieldAccess(int reps) {
+        new C().timeInternalFieldAccess(reps);
+    }
+
+    // Test an intrinsic.
+    public int timeStringLength(int reps) {
+        int result = 0;
+        for (int i = 0; i < reps; ++i) {
+            result = "hello, world!".length();
+        }
+        return result;
+    }
+
+    public void timeEmptyStatic(int reps) {
+        C c = new C();
+        for (int i = 0; i < reps; ++i) {
+            c.emptyStatic();
+        }
+    }
+
+    public void timeEmptyVirtual(int reps) {
+        C c = new C();
+        for (int i = 0; i < reps; ++i) {
+            c.emptyVirtual();
+        }
+    }
+
+    public void timeEmptyInterface(int reps) {
+        I c = new C();
+        for (int i = 0; i < reps; ++i) {
+            c.emptyInterface();
+        }
+    }
+
+    public static class Inner {
+        private int i;
+        private void privateMethod() { ++i; }
+        protected void protectedMethod() { ++i; }
+        public void publicMethod() { ++i; }
+        void packageMethod() { ++i; }
+        final void finalPackageMethod() { ++i; }
+    }
+
+    public void timePrivateInnerPublicMethod(int reps) {
+        Inner inner = new Inner();
+        for (int i = 0; i < reps; ++i) {
+            inner.publicMethod();
+        }
+    }
+
+    public void timePrivateInnerProtectedMethod(int reps) {
+        Inner inner = new Inner();
+        for (int i = 0; i < reps; ++i) {
+            inner.protectedMethod();
+        }
+    }
+
+    public void timePrivateInnerPrivateMethod(int reps) {
+        Inner inner = new Inner();
+        for (int i = 0; i < reps; ++i) {
+            inner.privateMethod();
+        }
+    }
+
+    public void timePrivateInnerPackageMethod(int reps) {
+        Inner inner = new Inner();
+        for (int i = 0; i < reps; ++i) {
+            inner.packageMethod();
+        }
+    }
+
+    public void timePrivateInnerFinalPackageMethod(int reps) {
+        Inner inner = new Inner();
+        for (int i = 0; i < reps; ++i) {
+          inner.finalPackageMethod();
+        }
+    }
+}

benchmarks/MultiplicationBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * How much do various kinds of multiplication cost?
+ */
+public class MultiplicationBenchmark extends SimpleBenchmark {
+    public int timeMultiplyIntByConstant10(int reps) {
+        int result = 1;
+        for (int i = 0; i < reps; ++i) {
+            result *= 10;
+        }
+        return result;
+    }
+    public int timeMultiplyIntByConstant8(int reps) {
+        int result = 1;
+        for (int i = 0; i < reps; ++i) {
+            result *= 8;
+        }
+        return result;
+    }
+    public int timeMultiplyIntByVariable10(int reps) {
+        int result = 1;
+        int factor = 10;
+        for (int i = 0; i < reps; ++i) {
+            result *= factor;
+        }
+        return result;
+    }
+    public int timeMultiplyIntByVariable8(int reps) {
+        int result = 1;
+        int factor = 8;
+        for (int i = 0; i < reps; ++i) {
+            result *= factor;
+        }
+        return result;
+    }
+}

benchmarks/StringIterationBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * How do the various schemes for iterating through a string compare?
+ */
+public class StringIterationBenchmark extends SimpleBenchmark {
+    public void timeStringIteration0(int reps) {
+        String s = "hello, world!";
+        for (int rep = 0; rep < reps; ++rep) {
+            char ch;
+            for (int i = 0; i < s.length(); ++i) {
+                ch = s.charAt(i);
+            }
+        }
+    }
+    public void timeStringIteration1(int reps) {
+        String s = "hello, world!";
+        for (int rep = 0; rep < reps; ++rep) {
+            char ch;
+            for (int i = 0, length = s.length(); i < length; ++i) {
+                ch = s.charAt(i);
+            }
+        }
+    }
+    public void timeStringIteration2(int reps) {
+        String s = "hello, world!";
+        for (int rep = 0; rep < reps; ++rep) {
+            char ch;
+            char[] chars = s.toCharArray();
+            for (int i = 0, length = chars.length; i < length; ++i) {
+                ch = chars[i];
+            }
+        }
+    }
+    public void timeStringToCharArray(int reps) {
+        String s = "hello, world!";
+        for (int rep = 0; rep < reps; ++rep) {
+            char[] chars = s.toCharArray();
+        }
+    }
+}

benchmarks/VirtualVersusInterfaceBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Is there a performance reason to "Prefer virtual over interface", as the
+ * Android documentation once claimed?
+ */
+public class VirtualVersusInterfaceBenchmark extends SimpleBenchmark {
+    public void timeMapPut(int reps) {
+        Map<String, String> map = new HashMap<String, String>();
+        for (int i = 0; i < reps; ++i) {
+            map.put("hello", "world");
+        }
+    }
+    public void timeHashMapPut(int reps) {
+        HashMap<String, String> map = new HashMap<String, String>();
+        for (int i = 0; i < reps; ++i) {
+            map.put("hello", "world");
+        }
+    }
+}

benchmarks/XmlParseBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+import java.util.List;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xmlpull.v1.XmlPullParser;
+
+public class XmlParseBenchmark extends SimpleBenchmark {
+
+    @Param String xmlFile;
+    ByteArrayInputStream inputStream;
+
+    static List<String> xmlFileValues = Arrays.asList(
+            "/etc/apns-conf.xml",
+            "/etc/media_profiles.xml",
+            "/etc/permissions/features.xml"
+    );
+
+    private SAXParser saxParser;
+    private DocumentBuilder documentBuilder;
+    private Constructor<? extends XmlPullParser> kxmlConstructor;
+    private Constructor<? extends XmlPullParser> expatConstructor;
+
+    @SuppressWarnings("unchecked")
+    @Override protected void setUp() throws Exception {
+        byte[] xmlBytes = getXmlBytes();
+        inputStream = new ByteArrayInputStream(xmlBytes);
+        inputStream.mark(xmlBytes.length);
+
+        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+        saxParser = saxParserFactory.newSAXParser();
+
+        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+        documentBuilder = builderFactory.newDocumentBuilder();
+
+        kxmlConstructor = (Constructor) Class.forName("org.kxml2.io.KXmlParser").getConstructor();
+        expatConstructor = (Constructor) Class.forName("org.apache.harmony.xml.ExpatPullParser")
+                .getConstructor();
+    }
+
+    private byte[] getXmlBytes() throws IOException {
+        FileInputStream fileIn = new FileInputStream(xmlFile);
+        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+        int count;
+        byte[] buffer = new byte[1024];
+        while ((count = fileIn.read(buffer)) != -1) {
+            bytesOut.write(buffer, 0, count);
+        }
+        fileIn.close();
+        return bytesOut.toByteArray();
+    }
+
+    public int timeSax(int reps) throws IOException, SAXException {
+        int elementCount = 0;
+        for (int i = 0; i < reps; i++) {
+            inputStream.reset();
+            ElementCounterSaxHandler elementCounterSaxHandler = new ElementCounterSaxHandler();
+            saxParser.parse(inputStream, elementCounterSaxHandler);
+            elementCount += elementCounterSaxHandler.elementCount;
+        }
+        return elementCount;
+    }
+
+    private static class ElementCounterSaxHandler extends DefaultHandler {
+        int elementCount = 0;
+        @Override public void startElement(String uri, String localName,
+                String qName, Attributes attributes) {
+            elementCount++;
+        }
+    }
+
+    public int timeDom(int reps) throws IOException, SAXException {
+        int elementCount = 0;
+        for (int i = 0; i < reps; i++) {
+            inputStream.reset();
+            Document document = documentBuilder.parse(inputStream);
+            elementCount += countDomElements(document.getDocumentElement());
+        }
+        return elementCount;
+    }
+
+    private int countDomElements(Node node) {
+        int result = 0;
+        for (; node != null; node = node.getNextSibling()) {
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                result++;
+            }
+            result += countDomElements(node.getFirstChild());
+        }
+        return result;
+    }
+
+    public int timeExpat(int reps) throws Exception {
+        return testXmlPull(expatConstructor, reps);
+    }
+
+    public int timeKxml(int reps) throws Exception {
+        return testXmlPull(kxmlConstructor, reps);
+    }
+
+    private int testXmlPull(Constructor<? extends XmlPullParser> constructor, int reps)
+            throws Exception {
+        int elementCount = 0;
+        for (int i = 0; i < reps; i++) {
+            inputStream.reset();
+            XmlPullParser xmlPullParser = constructor.newInstance();
+            xmlPullParser.setInput(inputStream, "UTF-8");
+            int type;
+            while ((type = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) {
+                if (type == XmlPullParser.START_TAG) {
+                    elementCount++;
+                }
+            }
+        }
+        return elementCount;
+    }
+
+    public static void main(String[] args) {
+        Runner.main(XmlParseBenchmark.class, args);
+    }
+}

benchmarks/regression/AnnotatedElementBenchmark.java

+/*
+ * Copyright (C) 2011 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 benchmarks.regression;
+
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class AnnotatedElementBenchmark extends SimpleBenchmark {
+
+    private Class<?> type;
+    private Field field;
+    private Method method;
+
+    @Override protected void setUp() throws Exception {
+        type = Type.class;
+        field = Type.class.getField("field");
+        method = Type.class.getMethod("method", String.class);
+    }
+
+
+    // get annotations by member type and method
+
+    public void timeGetTypeAnnotations(int reps) {
+        for (int i = 0; i < reps; i++) {
+            type.getAnnotations();
+        }
+    }
+
+    public void timeGetFieldAnnotations(int reps) {
+        for (int i = 0; i < reps; i++) {
+            field.getAnnotations();
+        }
+    }
+
+    public void timeGetMethodAnnotations(int reps) {
+        for (int i = 0; i < reps; i++) {
+            method.getAnnotations();
+        }
+    }
+
+    public void timeGetParameterAnnotations(int reps) {
+        for (int i = 0; i < reps; i++) {
+            method.getParameterAnnotations();
+        }
+    }
+
+    public void timeGetTypeAnnotation(int reps) {
+        for (int i = 0; i < reps; i++) {
+            type.getAnnotation(Marker.class);
+        }
+    }
+
+    public void timeGetFieldAnnotation(int reps) {
+        for (int i = 0; i < reps; i++) {
+            field.getAnnotation(Marker.class);
+        }
+    }
+
+    public void timeGetMethodAnnotation(int reps) {
+        for (int i = 0; i < reps; i++) {
+            method.getAnnotation(Marker.class);
+        }
+    }
+
+    public void timeIsTypeAnnotationPresent(int reps) {
+        for (int i = 0; i < reps; i++) {
+            type.isAnnotationPresent(Marker.class);
+        }
+    }
+
+    public void timeIsFieldAnnotationPresent(int reps) {
+        for (int i = 0; i < reps; i++) {
+            field.isAnnotationPresent(Marker.class);
+        }
+    }
+
+    public void timeIsMethodAnnotationPresent(int reps) {
+        for (int i = 0; i < reps; i++) {
+            method.isAnnotationPresent(Marker.class);
+        }
+    }
+
+    // get annotations by result size
+
+    public void timeGetAllReturnsLargeAnnotation(int reps) {
+        for (int i = 0; i < reps; i++) {
+            HasLargeAnnotation.class.getAnnotations();
+        }
+    }
+
+    public void timeGetAllReturnsSmallAnnotation(int reps) {
+        for (int i = 0; i < reps; i++) {
+            HasSmallAnnotation.class.getAnnotations();
+        }
+    }
+
+    public void timeGetAllReturnsMarkerAnnotation(int reps) {
+        for (int i = 0; i < reps; i++) {
+            HasMarkerAnnotation.class.getAnnotations();
+        }
+    }
+
+    public void timeGetAllReturnsNoAnnotation(int reps) {
+        for (int i = 0; i < reps; i++) {
+            HasNoAnnotations.class.getAnnotations();
+        }
+    }
+
+    public void timeGetAllReturnsThreeAnnotations(int reps) {
+        for (int i = 0; i < reps; i++) {
+            HasThreeAnnotations.class.getAnnotations();
+        }
+    }
+
+
+    // get annotations with inheritance
+
+    public void timeGetAnnotationsOnSubclass(int reps) {
+        for (int i = 0; i < reps; i++) {
+            ExtendsHasThreeAnnotations.class.getAnnotations();
+        }
+    }
+
+    public void timeGetDeclaredAnnotationsOnSubclass(int reps) {
+        for (int i = 0; i < reps; i++) {
+            ExtendsHasThreeAnnotations.class.getAnnotations();
+        }
+    }
+
+
+    // the annotated elements
+
+    @Marker
+    public class Type {
+        @Marker public String field;
+        @Marker public void method(@Marker String parameter) {}
+    }
+
+    @Large(a = "on class", b = {"A", "B", "C" },
+            c = @Small(e="E1", f=1695938256, g=7264081114510713000L),
+            d = { @Small(e="E2", f=1695938256, g=7264081114510713000L) })
+    public class HasLargeAnnotation {}
+
+    @Small(e="E1", f=1695938256, g=7264081114510713000L)
+    public class HasSmallAnnotation {}
+
+    @Marker
+    public class HasMarkerAnnotation {}
+
+    public class HasNoAnnotations {}
+
+    @Large(a = "on class", b = {"A", "B", "C" },
+            c = @Small(e="E1", f=1695938256, g=7264081114510713000L),
+            d = { @Small(e="E2", f=1695938256, g=7264081114510713000L) })
+    @Small(e="E1", f=1695938256, g=7264081114510713000L)
+    @Marker
+    public class HasThreeAnnotations {}
+
+    public class ExtendsHasThreeAnnotations {}
+
+
+    // the annotations
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Marker {}
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Large {
+        String a() default "";
+        String[] b() default {};
+        Small c() default @Small;
+        Small[] d() default {};
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Small {
+        String e() default "";
+        int f() default 0;
+        long g() default 0L;
+    }
+
+    public static void main(String[] args) throws Exception {
+        Runner.main(AnnotatedElementBenchmark.class, args);
+    }
+}

benchmarks/regression/BigIntegerBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks.regression;
+
+import java.math.BigInteger;
+import java.util.Random;
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class BigIntegerBenchmark extends SimpleBenchmark {
+    public void timeRandomDivision(int reps) throws Exception {
+        Random r = new Random();
+        BigInteger x = new BigInteger(1024, r);
+        BigInteger y = new BigInteger(1024, r);
+        for (int i = 0; i < reps; ++i) {
+            x.divide(y);
+        }
+    }
+
+    public void timeRandomGcd(int reps) throws Exception {
+        Random r = new Random();
+        BigInteger x = new BigInteger(1024, r);
+        BigInteger y = new BigInteger(1024, r);
+        for (int i = 0; i < reps; ++i) {
+            x.gcd(y);
+        }
+    }
+
+    public void timeRandomMultiplication(int reps) throws Exception {
+        Random r = new Random();
+        BigInteger x = new BigInteger(1024, r);
+        BigInteger y = new BigInteger(1024, r);
+        for (int i = 0; i < reps; ++i) {
+            x.multiply(y);
+        }
+    }
+}

benchmarks/regression/BitSetBenchmark.java

+/*
+ * Copyright (C) 2011 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 benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+import java.util.BitSet;
+
+public class BitSetBenchmark extends SimpleBenchmark {
+    @Param({ "1000", "10000" })
+    private int size;
+
+    private BitSet bs;
+
+    @Override protected void setUp() throws Exception {
+        bs = new BitSet(size);
+    }
+
+    public void timeIsEmptyTrue(int reps) {
+        for (int i = 0; i < reps; ++i) {
+            if (!bs.isEmpty()) throw new RuntimeException();
+        }
+    }
+
+    public void timeIsEmptyFalse(int reps) {
+        bs.set(bs.size() - 1);
+        for (int i = 0; i < reps; ++i) {
+            if (bs.isEmpty()) throw new RuntimeException();
+        }
+    }
+
+    public void timeGet(int reps) {
+        for (int i = 0; i < reps; ++i) {
+            bs.get(i % size);
+        }
+    }
+
+    public void timeClear(int reps) {
+        for (int i = 0; i < reps; ++i) {
+            bs.clear(i % size);
+        }
+    }
+
+    public void timeSet(int reps) {
+        for (int i = 0; i < reps; ++i) {
+            bs.set(i % size);
+        }
+    }
+
+    public void timeSetOn(int reps) {
+        for (int i = 0; i < reps; ++i) {
+            bs.set(i % size, true);
+        }
+    }
+
+    public void timeSetOff(int reps) {
+        for (int i = 0; i < reps; ++i) {
+            bs.set(i % size, false);
+        }
+    }
+}

benchmarks/regression/ByteBufferBenchmark.java

+/*
+ * Copyright (C) 2010 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 benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.Arrays;
+import java.util.Collection;
+
+public class ByteBufferBenchmark extends SimpleBenchmark {
+    public enum MyByteOrder {
+        BIG(ByteOrder.BIG_ENDIAN), LITTLE(ByteOrder.LITTLE_ENDIAN);
+        final ByteOrder byteOrder;
+        MyByteOrder(ByteOrder byteOrder) {
+            this.byteOrder = byteOrder;
+        }
+    }
+
+    @Param private MyByteOrder byteOrder;
+
+    @Param({"true", "false"}) private boolean aligned;
+
+    enum MyBufferType {
+        DIRECT, HEAP, MAPPED;
+    }
+    @Param private MyBufferType bufferType;
+
+    public static ByteBuffer newBuffer(MyByteOrder byteOrder, boolean aligned, MyBufferType bufferType) throws IOException {
+        int size = aligned ? 8192 : 8192 + 8 + 1;
+        ByteBuffer result = null;
+        switch (bufferType) {
+        case DIRECT:
+            result = ByteBuffer.allocateDirect(size);
+            break;
+        case HEAP:
+            result = ByteBuffer.allocate(size);
+            break;
+        case MAPPED:
+            File tmpFile = new File("/sdcard/bm.tmp");
+            if (new File("/tmp").isDirectory()) {
+                // We're running on the desktop.
+                tmpFile = File.createTempFile("MappedByteBufferTest", ".tmp");
+            }
+            tmpFile.createNewFile();
+            tmpFile.deleteOnExit();
+            RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw");
+            raf.setLength(8192*8);
+            FileChannel fc = raf.getChannel();
+            result = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());
+            break;
+        }
+        result.order(byteOrder.byteOrder);
+        result.position(aligned ? 0 : 1);
+        return result;
+    }
+
+    //
+    // peeking
+    //
+
+    public void timeByteBuffer_getByte(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.get();
+            }
+        }
+    }
+
+    public void timeByteBuffer_getByteArray(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        byte[] dst = new byte[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(aligned ? 0 : 1);
+                src.get(dst);
+            }
+        }
+    }
+
+    public void timeByteBuffer_getByte_indexed(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.get(i);
+            }
+        }
+    }
+
+    public void timeByteBuffer_getChar(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getChar();
+            }
+        }
+    }
+
+    public void timeCharBuffer_getCharArray(int reps) throws Exception {
+        CharBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asCharBuffer();
+        char[] dst = new char[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    public void timeByteBuffer_getChar_indexed(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getChar(i * 2);
+            }
+        }
+    }
+
+    public void timeByteBuffer_getDouble(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getDouble();
+            }
+        }
+    }
+
+    public void timeDoubleBuffer_getDoubleArray(int reps) throws Exception {
+        DoubleBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asDoubleBuffer();
+        double[] dst = new double[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    public void timeByteBuffer_getFloat(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getFloat();
+            }
+        }
+    }
+
+    public void timeFloatBuffer_getFloatArray(int reps) throws Exception {
+        FloatBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asFloatBuffer();
+        float[] dst = new float[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    public void timeByteBuffer_getInt(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getInt();
+            }
+        }
+    }
+
+    public void timeIntBuffer_getIntArray(int reps) throws Exception {
+        IntBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asIntBuffer();
+        int[] dst = new int[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    public void timeByteBuffer_getLong(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getLong();
+            }
+        }
+    }
+
+    public void timeLongBuffer_getLongArray(int reps) throws Exception {
+        LongBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asLongBuffer();
+        long[] dst = new long[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    public void timeByteBuffer_getShort(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getShort();
+            }
+        }
+    }
+
+    public void timeShortBuffer_getShortArray(int reps) throws Exception {
+        ShortBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asShortBuffer();
+        short[] dst = new short[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    //
+    // poking
+    //
+
+    public void timeByteBuffer_putByte(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(0);
+            for (int i = 0; i < 1024; ++i) {
+                src.put((byte) 0);
+            }
+        }
+    }
+
+    public void timeByteBuffer_putByteArray(int reps) throws Exception {
+        ByteBuffer dst = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        byte[] src = new byte[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(aligned ? 0 : 1);
+                dst.put(src);
+            }
+        }
+    }
+
+    public void timeByteBuffer_putChar(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putChar(' ');
+            }
+        }
+    }
+
+    public void timeCharBuffer_putCharArray(int reps) throws Exception {
+        CharBuffer dst = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asCharBuffer();
+        char[] src = new char[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    public void timeByteBuffer_putDouble(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putDouble(0.0);
+            }
+        }
+    }
+
+    public void timeDoubleBuffer_putDoubleArray(int reps) throws Exception {
+        DoubleBuffer dst = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asDoubleBuffer();
+        double[] src = new double[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    public void timeByteBuffer_putFloat(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putFloat(0.0f);
+            }
+        }
+    }
+
+    public void timeFloatBuffer_putFloatArray(int reps) throws Exception {
+        FloatBuffer dst = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asFloatBuffer();
+        float[] src = new float[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    public void timeByteBuffer_putInt(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putInt(0);
+            }
+        }
+    }
+
+    public void timeIntBuffer_putIntArray(int reps) throws Exception {
+        IntBuffer dst = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asIntBuffer();
+        int[] src = new int[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    public void timeByteBuffer_putLong(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putLong(0L);
+            }
+        }
+    }
+
+    public void timeLongBuffer_putLongArray(int reps) throws Exception {
+        LongBuffer dst = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asLongBuffer();
+        long[] src = new long[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    public void timeByteBuffer_putShort(int reps) throws Exception {
+        ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+        for (int rep = 0; rep < reps; ++rep) {
+            src.position(aligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putShort((short) 0);
+            }
+        }
+    }
+
+    public void timeShortBuffer_putShortArray(int reps) throws Exception {
+        ShortBuffer dst = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType).asShortBuffer();
+        short[] src = new short[1024];
+        for (int rep = 0; rep < reps; ++rep) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+/*
+    public void time_new_byteArray(int reps) throws Exception {
+        for (int rep = 0; rep < reps; ++rep) {
+            byte[] bs = new byte[8192];
+        }
+    }
+
+    public void time_ByteBuffer_allocate(int reps) throws Exception {
+        for (int rep = 0; rep < reps; ++rep) {
+            ByteBuffer bs = ByteBuffer.allocate(8192);
+        }
+    }
+    */
+}

benchmarks/regression/ByteBufferScalarVersusVectorBenchmark.java

+/*
+ * Copyright (C) 2012 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 benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.Arrays;
+import java.util.Collection;
+
+public class ByteBufferScalarVersusVectorBenchmark extends SimpleBenchmark {
+  @Param private ByteBufferBenchmark.MyByteOrder byteOrder;
+  @Param({"true", "false"}) private boolean aligned;
+  @Param private ByteBufferBenchmark.MyBufferType bufferType;
+
+  public void timeManualByteBufferCopy(int reps) throws Exception {
+    ByteBuffer src = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+    ByteBuffer dst = ByteBufferBenchmark.newBuffer(byteOrder, aligned, bufferType);
+    for (int rep = 0; rep < reps; ++rep) {
+      src.position(0);
+      dst.position(0);
+      for (int i = 0; i < 8192; ++i) {
+        dst.put(src.get());
+      }
+    }
+  }
+
+  public void timeByteBufferBulkGet(int reps) throws Exception {
+    ByteBuffer src = ByteBuffer.allocate(aligned ? 8192 : 8192 + 1);
+    byte[] dst = new byte[8192];
+    for (int rep = 0; rep < reps; ++rep) {
+      src.position(aligned ? 0 : 1);
+      src.get(dst, 0, dst.length);
+    }
+  }
+
+  public void timeDirectByteBufferBulkGet(int reps) throws Exception {
+    ByteBuffer src = ByteBuffer.allocateDirect(aligned ? 8192 : 8192 + 1);
+    byte[] dst = new byte[8192];
+    for (int rep = 0; rep < reps; ++rep) {
+      src.position(aligned ? 0 : 1);
+      src.get(dst, 0, dst.length);
+    }
+  }
+}

benchmarks/regression/CharacterBenchmark.java

+/*
+ * 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 benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+/**
+ * Tests various Character methods, intended for testing multiple
+ * implementations against each other.
+ */
+public class CharacterBenchmark extends SimpleBenchmark {
+
+    @Param private CharacterSet characterSet;
+
+    @Param private Overload overload;
+
+    private char[] chars;
+
+    @Override protected void setUp() throws Exception {
+        this.chars = characterSet.chars;
+    }
+
+    public enum Overload { CHAR, INT }
+
+    @Override public double nanosToUnits(double nanos) {
+        return nanos / 65536;
+    }
+
+    public enum CharacterSet {
+        ASCII(128),
+        UNICODE(65536);
+        final char[] chars;
+        CharacterSet(int size) {
+            this.chars = new char[65536];
+            for (int i = 0; i < 65536; ++i) {
+                chars[i] = (char) (i % size);
+            }
+        }
+    }
+
+    // A fake benchmark to give us a baseline.
+    public boolean timeIsSpace(int reps) {
+        boolean dummy = false;
+        if (overload == Overload.CHAR) {
+            for (int i = 0; i < reps; ++i) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    dummy ^= ((char) ch == ' ');
+                }
+            }
+        } else {
+            for (int i = 0; i < reps; ++i) {