summaryrefslogtreecommitdiffstats
path: root/benchmarks
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks')
-rw-r--r--benchmarks/AdditionBenchmark.java87
-rw-r--r--benchmarks/ArrayCopyBenchmark.java57
-rw-r--r--benchmarks/ArrayIterationBenchmark.java58
-rw-r--r--benchmarks/ArrayListIterationBenchmark.java51
-rw-r--r--benchmarks/BufferedZipFileBenchmark.java79
-rw-r--r--benchmarks/FieldAccessBenchmark.java105
-rw-r--r--benchmarks/Foo.java24
-rw-r--r--benchmarks/HashedCollectionsBenchmark.java71
-rw-r--r--benchmarks/MethodInvocationBenchmark.java145
-rw-r--r--benchmarks/MultiplicationBenchmark.java57
-rw-r--r--benchmarks/StringIterationBenchmark.java61
-rw-r--r--benchmarks/VirtualVersusInterfaceBenchmark.java43
-rw-r--r--benchmarks/XmlParseBenchmark.java153
-rw-r--r--benchmarks/regression/AnnotatedElementBenchmark.java203
-rw-r--r--benchmarks/regression/BigIntegerBenchmark.java51
-rw-r--r--benchmarks/regression/BitSetBenchmark.java75
-rw-r--r--benchmarks/regression/ByteBufferBenchmark.java411
-rw-r--r--benchmarks/regression/ByteBufferScalarVersusVectorBenchmark.java63
-rw-r--r--benchmarks/regression/CharacterBenchmark.java299
-rw-r--r--benchmarks/regression/CharsetBenchmark.java145
-rw-r--r--benchmarks/regression/CharsetForNameBenchmark.java45
-rw-r--r--benchmarks/regression/ChecksumBenchmark.java52
-rw-r--r--benchmarks/regression/CipherBenchmark.java148
-rw-r--r--benchmarks/regression/DateToStringBenchmark.java67
-rw-r--r--benchmarks/regression/DefaultCharsetBenchmark.java29
-rw-r--r--benchmarks/regression/DigestBenchmark.java65
-rw-r--r--benchmarks/regression/DnsBenchmark.java51
-rw-r--r--benchmarks/regression/DoPrivilegedBenchmark.java75
-rw-r--r--benchmarks/regression/DoubleBenchmark.java56
-rw-r--r--benchmarks/regression/EqualsHashCodeBenchmark.java67
-rw-r--r--benchmarks/regression/ExpensiveObjectsBenchmark.java150
-rw-r--r--benchmarks/regression/FloatBenchmark.java56
-rw-r--r--benchmarks/regression/FormatterBenchmark.java133
-rw-r--r--benchmarks/regression/HostnameVerifierBenchmark.java170
-rw-r--r--benchmarks/regression/IntConstantDivisionBenchmark.java82
-rw-r--r--benchmarks/regression/IntConstantMultiplicationBenchmark.java103
-rw-r--r--benchmarks/regression/IntConstantRemainderBenchmark.java79
-rw-r--r--benchmarks/regression/IntegerBenchmark.java139
-rw-r--r--benchmarks/regression/IntegralToStringBenchmark.java172
-rw-r--r--benchmarks/regression/JarFileBenchmark.java40
-rw-r--r--benchmarks/regression/KeyPairGeneratorBenchmark.java65
-rw-r--r--benchmarks/regression/LoopingBackwardsBenchmark.java50
-rw-r--r--benchmarks/regression/MathBenchmark.java368
-rw-r--r--benchmarks/regression/MessageDigestBenchmark.java49
-rw-r--r--benchmarks/regression/MutableIntBenchmark.java92
-rw-r--r--benchmarks/regression/NativeMethodBenchmark.java79
-rw-r--r--benchmarks/regression/ParseBenchmark.java217
-rw-r--r--benchmarks/regression/ParseBenchmarkData.zipbin0 -> 135922 bytes
-rw-r--r--benchmarks/regression/PriorityQueueBenchmark.java84
-rw-r--r--benchmarks/regression/PropertyAccessBenchmark.java116
-rw-r--r--benchmarks/regression/RandomBenchmark.java52
-rw-r--r--benchmarks/regression/RealToStringBenchmark.java130
-rw-r--r--benchmarks/regression/ReflectionBenchmark.java182
-rw-r--r--benchmarks/regression/SSLSocketBenchmark.java109
-rw-r--r--benchmarks/regression/SchemePrefixBenchmark.java81
-rw-r--r--benchmarks/regression/SerializationBenchmark.java217
-rw-r--r--benchmarks/regression/SignatureBenchmark.java128
-rw-r--r--benchmarks/regression/StrictMathBenchmark.java356
-rw-r--r--benchmarks/regression/StringBenchmark.java46
-rw-r--r--benchmarks/regression/StringBuilderBenchmark.java132
-rw-r--r--benchmarks/regression/StringCaseMappingBenchmark.java150
-rw-r--r--benchmarks/regression/StringIsEmptyBenchmark.java54
-rw-r--r--benchmarks/regression/StringLengthBenchmark.java30
-rw-r--r--benchmarks/regression/StringSplitBenchmark.java60
-rw-r--r--benchmarks/regression/StringToRealBenchmark.java47
-rw-r--r--benchmarks/regression/SystemPropertiesBenchmark.java29
-rw-r--r--benchmarks/regression/ThreadLocalBenchmark.java35
-rw-r--r--benchmarks/regression/TimeZoneBenchmark.java61
-rw-r--r--benchmarks/regression/URLConnectionBenchmark.java132
-rw-r--r--benchmarks/regression/XmlEntitiesBenchmark.java71
70 files changed, 7239 insertions, 0 deletions
diff --git a/benchmarks/AdditionBenchmark.java b/benchmarks/AdditionBenchmark.java
new file mode 100644
index 0000000..a18856e
--- /dev/null
+++ b/benchmarks/AdditionBenchmark.java
@@ -0,0 +1,87 @@
+/*
+ * 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;
+ }
+}
diff --git a/benchmarks/ArrayCopyBenchmark.java b/benchmarks/ArrayCopyBenchmark.java
new file mode 100644
index 0000000..75ad243
--- /dev/null
+++ b/benchmarks/ArrayCopyBenchmark.java
@@ -0,0 +1,57 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/benchmarks/ArrayIterationBenchmark.java b/benchmarks/ArrayIterationBenchmark.java
new file mode 100644
index 0000000..bdc255b
--- /dev/null
+++ b/benchmarks/ArrayIterationBenchmark.java
@@ -0,0 +1,58 @@
+/*
+ * 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;
+ }
+ }
+ }
+}
diff --git a/benchmarks/ArrayListIterationBenchmark.java b/benchmarks/ArrayListIterationBenchmark.java
new file mode 100644
index 0000000..4e5f145
--- /dev/null
+++ b/benchmarks/ArrayListIterationBenchmark.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+ }
+ }
+ }
+}
diff --git a/benchmarks/BufferedZipFileBenchmark.java b/benchmarks/BufferedZipFileBenchmark.java
new file mode 100644
index 0000000..f4d3822
--- /dev/null
+++ b/benchmarks/BufferedZipFileBenchmark.java
@@ -0,0 +1,79 @@
+/*
+ * 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();
+ }
+ }
+}
diff --git a/benchmarks/FieldAccessBenchmark.java b/benchmarks/FieldAccessBenchmark.java
new file mode 100644
index 0000000..19cb060
--- /dev/null
+++ b/benchmarks/FieldAccessBenchmark.java
@@ -0,0 +1,105 @@
+/*
+ * 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;
+ }
+}
diff --git a/benchmarks/Foo.java b/benchmarks/Foo.java
new file mode 100644
index 0000000..d288dd6
--- /dev/null
+++ b/benchmarks/Foo.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+}
diff --git a/benchmarks/HashedCollectionsBenchmark.java b/benchmarks/HashedCollectionsBenchmark.java
new file mode 100644
index 0000000..a826271
--- /dev/null
+++ b/benchmarks/HashedCollectionsBenchmark.java
@@ -0,0 +1,71 @@
+/*
+ * 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");
+ }
+ }
+}
diff --git a/benchmarks/MethodInvocationBenchmark.java b/benchmarks/MethodInvocationBenchmark.java
new file mode 100644
index 0000000..7a5e1b6
--- /dev/null
+++ b/benchmarks/MethodInvocationBenchmark.java
@@ -0,0 +1,145 @@
+/*
+ * 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();
+ }
+ }
+}
diff --git a/benchmarks/MultiplicationBenchmark.java b/benchmarks/MultiplicationBenchmark.java
new file mode 100644
index 0000000..b2f945b
--- /dev/null
+++ b/benchmarks/MultiplicationBenchmark.java
@@ -0,0 +1,57 @@
+/*
+ * 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;
+ }
+}
diff --git a/benchmarks/StringIterationBenchmark.java b/benchmarks/StringIterationBenchmark.java
new file mode 100644
index 0000000..22c6ae2
--- /dev/null
+++ b/benchmarks/StringIterationBenchmark.java
@@ -0,0 +1,61 @@
+/*
+ * 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();
+ }
+ }
+}
diff --git a/benchmarks/VirtualVersusInterfaceBenchmark.java b/benchmarks/VirtualVersusInterfaceBenchmark.java
new file mode 100644
index 0000000..f029c81
--- /dev/null
+++ b/benchmarks/VirtualVersusInterfaceBenchmark.java
@@ -0,0 +1,43 @@
+/*
+ * 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");
+ }
+ }
+}
diff --git a/benchmarks/XmlParseBenchmark.java b/benchmarks/XmlParseBenchmark.java
new file mode 100644
index 0000000..b5e7b93
--- /dev/null
+++ b/benchmarks/XmlParseBenchmark.java
@@ -0,0 +1,153 @@
+/*
+ * 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);
+ }
+}
diff --git a/benchmarks/regression/AnnotatedElementBenchmark.java b/benchmarks/regression/AnnotatedElementBenchmark.java
new file mode 100644
index 0000000..6c33968
--- /dev/null
+++ b/benchmarks/regression/AnnotatedElementBenchmark.java
@@ -0,0 +1,203 @@
+/*
+ * 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);
+ }
+}
diff --git a/benchmarks/regression/BigIntegerBenchmark.java b/benchmarks/regression/BigIntegerBenchmark.java
new file mode 100644
index 0000000..841b901
--- /dev/null
+++ b/benchmarks/regression/BigIntegerBenchmark.java
@@ -0,0 +1,51 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/benchmarks/regression/BitSetBenchmark.java b/benchmarks/regression/BitSetBenchmark.java
new file mode 100644
index 0000000..ee91993
--- /dev/null
+++ b/benchmarks/regression/BitSetBenchmark.java
@@ -0,0 +1,75 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/benchmarks/regression/ByteBufferBenchmark.java b/benchmarks/regression/ByteBufferBenchmark.java
new file mode 100644
index 0000000..7812013
--- /dev/null
+++ b/benchmarks/regression/ByteBufferBenchmark.java
@@ -0,0 +1,411 @@
+/*
+ * 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);
+ }
+ }
+ */
+}
diff --git a/benchmarks/regression/ByteBufferScalarVersusVectorBenchmark.java b/benchmarks/regression/ByteBufferScalarVersusVectorBenchmark.java
new file mode 100644
index 0000000..7c75deb
--- /dev/null
+++ b/benchmarks/regression/ByteBufferScalarVersusVectorBenchmark.java
@@ -0,0 +1,63 @@
+/*
+ * 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);
+ }
+ }
+}
diff --git a/benchmarks/regression/CharacterBenchmark.java b/benchmarks/regression/CharacterBenchmark.java
new file mode 100644
index 0000000..953513b
--- /dev/null
+++ b/benchmarks/regression/CharacterBenchmark.java
@@ -0,0 +1,299 @@
+/*
+ * 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) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ dummy ^= (ch == ' ');
+ }
+ }
+ }
+ return dummy;
+ }
+
+ public void timeDigit(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.digit(chars[ch], 10);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.digit((int) chars[ch], 10);
+ }
+ }
+ }
+ }
+
+ public void timeGetNumericValue(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.getNumericValue(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.getNumericValue((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsDigit(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isDigit(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isDigit((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsIdentifierIgnorable(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isIdentifierIgnorable(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isIdentifierIgnorable((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsJavaIdentifierPart(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isJavaIdentifierPart(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isJavaIdentifierPart((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsJavaIdentifierStart(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isJavaIdentifierStart(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isJavaIdentifierStart((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsLetter(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLetter(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLetter((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsLetterOrDigit(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLetterOrDigit(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLetterOrDigit((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsLowerCase(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLowerCase(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isLowerCase((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsSpaceChar(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isSpaceChar(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isSpaceChar((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsUpperCase(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isUpperCase(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isUpperCase((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeIsWhitespace(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isWhitespace(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.isWhitespace((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeToLowerCase(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.toLowerCase(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.toLowerCase((int) chars[ch]);
+ }
+ }
+ }
+ }
+
+ public void timeToUpperCase(int reps) {
+ if (overload == Overload.CHAR) {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.toUpperCase(chars[ch]);
+ }
+ }
+ } else {
+ for (int i = 0; i < reps; ++i) {
+ for (int ch = 0; ch < 65536; ++ch) {
+ Character.toUpperCase((int) chars[ch]);
+ }
+ }
+ }
+ }
+}
diff --git a/benchmarks/regression/CharsetBenchmark.java b/benchmarks/regression/CharsetBenchmark.java
new file mode 100644
index 0000000..6ecada7
--- /dev/null
+++ b/benchmarks/regression/CharsetBenchmark.java
@@ -0,0 +1,145 @@
+/*
+ * 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.nio.charset.Charset;
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class CharsetBenchmark extends SimpleBenchmark {
+ @Param({ "1", "10", "100", "1000", "10000" })
+ private int length;
+
+ // canonical => canonical charset name
+ // built-in => guaranteed-present charset
+ // special-case => libcore treats this charset specially for performance
+ @Param({
+ "UTF-16", // canonical, built-in, non-special-case
+ "UTF-8", // canonical, built-in, special-case
+ "UTF8", // non-canonical, built-in, special-case
+ "ISO-8859-1", // canonical, built-in, special-case
+ "8859_1", // non-canonical, built-in, special-case
+ "ISO-8859-2", // canonical, non-built-in, non-special-case
+ "8859_2", // non-canonical, non-built-in, non-special-case
+ "US-ASCII", // canonical, built-in, special-case
+ "ASCII" // non-canonical, built-in, special-case
+ })
+ private String name;
+
+ public void time_new_String_BString(int reps) throws Exception {
+ byte[] bytes = makeBytes(makeString(length));
+ for (int i = 0; i < reps; ++i) {
+ new String(bytes, name);
+ }
+ }
+
+ public void time_new_String_BII(int reps) throws Exception {
+ byte[] bytes = makeBytes(makeString(length));
+ for (int i = 0; i < reps; ++i) {
+ new String(bytes, 0, bytes.length);
+ }
+ }
+
+ public void time_new_String_BIIString(int reps) throws Exception {
+ byte[] bytes = makeBytes(makeString(length));
+ for (int i = 0; i < reps; ++i) {
+ new String(bytes, 0, bytes.length, name);
+ }
+ }
+
+ public void time_String_getBytes(int reps) throws Exception {
+ String string = makeString(length);
+ for (int i = 0; i < reps; ++i) {
+ string.getBytes(name);
+ }
+ }
+
+ // FIXME: benchmark this pure-java implementation for US-ASCII and ISO-8859-1 too!
+
+ /**
+ * Translates the given characters to US-ASCII or ISO-8859-1 bytes, using the fact that
+ * Unicode code points between U+0000 and U+007f inclusive are identical to US-ASCII, while
+ * U+0000 to U+00ff inclusive are identical to ISO-8859-1.
+ */
+ private static byte[] toDirectMappedBytes(char[] chars, int offset, int length, int maxValidChar) {
+ byte[] result = new byte[length];
+ int o = offset;
+ for (int i = 0; i < length; ++i) {
+ int ch = chars[o++];
+ result[i] = (byte) ((ch <= maxValidChar) ? ch : '?');
+ }
+ return result;
+ }
+
+ private static byte[] toUtf8Bytes(char[] chars, int offset, int length) {
+ UnsafeByteSequence result = new UnsafeByteSequence(length);
+ toUtf8Bytes(chars, offset, length, result);
+ return result.toByteArray();
+ }
+
+ private static void toUtf8Bytes(char[] chars, int offset, int length, UnsafeByteSequence out) {
+ final int end = offset + length;
+ for (int i = offset; i < end; ++i) {
+ int ch = chars[i];
+ if (ch < 0x80) {
+ // One byte.
+ out.write(ch);
+ } else if (ch < 0x800) {
+ // Two bytes.
+ out.write((ch >> 6) | 0xc0);
+ out.write((ch & 0x3f) | 0x80);
+ } else if (ch >= Character.MIN_SURROGATE && ch <= Character.MAX_SURROGATE) {
+ // A supplementary character.
+ char high = (char) ch;
+ char low = (i + 1 != end) ? chars[i + 1] : '\u0000';
+ if (!Character.isSurrogatePair(high, low)) {
+ out.write('?');
+ continue;
+ }
+ // Now we know we have a *valid* surrogate pair, we can consume the low surrogate.
+ ++i;
+ ch = Character.toCodePoint(high, low);
+ // Four bytes.
+ out.write((ch >> 18) | 0xf0);
+ out.write(((ch >> 12) & 0x3f) | 0x80);
+ out.write(((ch >> 6) & 0x3f) | 0x80);
+ out.write((ch & 0x3f) | 0x80);
+ } else {
+ // Three bytes.
+ out.write((ch >> 12) | 0xe0);
+ out.write(((ch >> 6) & 0x3f) | 0x80);
+ out.write((ch & 0x3f) | 0x80);
+ }
+ }
+ }
+
+ private static String makeString(int length) {
+ StringBuilder result = new StringBuilder(length);
+ for (int i = 0; i < length; ++i) {
+ result.append('A' + (i % 26));
+ }
+ return result.toString();
+ }
+
+ private static byte[] makeBytes(String s) {
+ try {
+ return s.getBytes("US-ASCII");
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/benchmarks/regression/CharsetForNameBenchmark.java b/benchmarks/regression/CharsetForNameBenchmark.java
new file mode 100644
index 0000000..87dfb8b
--- /dev/null
+++ b/benchmarks/regression/CharsetForNameBenchmark.java
@@ -0,0 +1,45 @@
+/*
+ * 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.nio.charset.Charset;
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class CharsetForNameBenchmark extends SimpleBenchmark {
+ // canonical => canonical charset name
+ // built-in => guaranteed-present charset
+ // special-case => libcore treats this charset specially for performance
+ @Param({
+ "UTF-16", // canonical, built-in, non-special-case
+ "UTF-8", // canonical, built-in, special-case
+ "UTF8", // non-canonical, built-in, special-case
+ "ISO-8859-1", // canonical, built-in, special-case
+ "8859_1", // non-canonical, built-in, special-case
+ "ISO-8859-2", // canonical, non-built-in, non-special-case
+ "8859_2", // non-canonical, non-built-in, non-special-case
+ "US-ASCII", // canonical, built-in, special-case
+ "ASCII" // non-canonical, built-in, special-case
+ })
+ private String charsetName;
+
+ public void timeCharsetForName(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ Charset.forName(charsetName);
+ }
+ }
+}
diff --git a/benchmarks/regression/ChecksumBenchmark.java b/benchmarks/regression/ChecksumBenchmark.java
new file mode 100644
index 0000000..0e7bf8d
--- /dev/null
+++ b/benchmarks/regression/ChecksumBenchmark.java
@@ -0,0 +1,52 @@
+/*
+ * 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.util.zip.Adler32;
+import java.util.zip.CRC32;
+
+public class ChecksumBenchmark extends SimpleBenchmark {
+ public void timeAdler_block(int reps) throws Exception {
+ byte[] bytes = new byte[10000];
+ Adler32 adler = new Adler32();
+ for (int i = 0; i < reps; ++i) {
+ adler.update(bytes);
+ }
+ }
+ public void timeAdler_byte(int reps) throws Exception {
+ Adler32 adler = new Adler32();
+ for (int i = 0; i < reps; ++i) {
+ adler.update(1);
+ }
+ }
+ public void timeCrc_block(int reps) throws Exception {
+ byte[] bytes = new byte[10000];
+ CRC32 crc = new CRC32();
+ for (int i = 0; i < reps; ++i) {
+ crc.update(bytes);
+ }
+ }
+ public void timeCrc_byte(int reps) throws Exception {
+ CRC32 crc = new CRC32();
+ for (int i = 0; i < reps; ++i) {
+ crc.update(1);
+ }
+ }
+}
diff --git a/benchmarks/regression/CipherBenchmark.java b/benchmarks/regression/CipherBenchmark.java
new file mode 100644
index 0000000..56d549b
--- /dev/null
+++ b/benchmarks/regression/CipherBenchmark.java
@@ -0,0 +1,148 @@
+/*
+ * 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.SimpleBenchmark;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * Cipher benchmarks. Only runs on AES currently because of the combinatorial
+ * explosion of the test as it stands.
+ */
+public class CipherBenchmark extends SimpleBenchmark {
+
+ private static final int DATA_SIZE = 8192;
+ private static final byte[] DATA = new byte[DATA_SIZE];
+
+ private static final int IV_SIZE = 16;
+
+ private static final byte[] IV = new byte[IV_SIZE];
+
+ static {
+ for (int i = 0; i < DATA_SIZE; i++) {
+ DATA[i] = (byte) i;
+ }
+ for (int i = 0; i < IV_SIZE; i++) {
+ IV[i] = (byte) i;
+ }
+ }
+
+ @Param private Algorithm algorithm;
+
+ public enum Algorithm {
+ AES,
+ };
+
+ @Param private Mode mode;
+
+ public enum Mode {
+ CBC,
+ CFB,
+ CTR,
+ ECB,
+ OFB,
+ };
+
+ @Param private Padding padding;
+
+ public enum Padding {
+ NOPADDING,
+ PKCS1PADDING,
+ };
+
+ @Param({"128", "192", "256"}) private int keySize;
+
+ @Param({"16", "32", "64", "128", "1024", "8192"}) private int inputSize;
+
+ @Param private Implementation implementation;
+
+ public enum Implementation { OpenSSL, BouncyCastle };
+
+ private String providerName;
+
+ // Key generation isn't part of the benchmark so cache the results
+ private static Map<Integer, SecretKey> KEY_SIZES = new HashMap<Integer, SecretKey>();
+
+ private String cipherAlgorithm;
+ private SecretKey key;
+
+ private byte[] output = new byte[DATA.length];
+
+ private Cipher cipherEncrypt;
+
+ private Cipher cipherDecrypt;
+
+ private AlgorithmParameterSpec spec;
+
+ @Override protected void setUp() throws Exception {
+ cipherAlgorithm = algorithm.toString() + "/" + mode.toString() + "/"
+ + padding.toString();
+
+ String keyAlgorithm = algorithm.toString();
+ key = KEY_SIZES.get(keySize);
+ if (key == null) {
+ KeyGenerator generator = KeyGenerator.getInstance(keyAlgorithm);
+ generator.init(keySize);
+ key = generator.generateKey();
+ KEY_SIZES.put(keySize, key);
+ }
+
+ switch (implementation) {
+ case OpenSSL:
+ providerName = "AndroidOpenSSL";
+ break;
+ case BouncyCastle:
+ providerName = "BC";
+ break;
+ default:
+ throw new RuntimeException(implementation.toString());
+ }
+
+ if (mode != Mode.ECB) {
+ spec = new IvParameterSpec(IV);
+ }
+
+ cipherEncrypt = Cipher.getInstance(cipherAlgorithm, providerName);
+ cipherEncrypt.init(Cipher.ENCRYPT_MODE, key, spec);
+
+ cipherDecrypt = Cipher.getInstance(cipherAlgorithm, providerName);
+ cipherDecrypt.init(Cipher.DECRYPT_MODE, key, spec);
+ }
+
+ public void timeEncrypt(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ cipherEncrypt.doFinal(DATA, 0, inputSize, output);
+ }
+ }
+
+ public void timeDecrypt(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ cipherDecrypt.doFinal(DATA, 0, inputSize, output);
+ }
+ }
+}
diff --git a/benchmarks/regression/DateToStringBenchmark.java b/benchmarks/regression/DateToStringBenchmark.java
new file mode 100644
index 0000000..15760c9
--- /dev/null
+++ b/benchmarks/regression/DateToStringBenchmark.java
@@ -0,0 +1,67 @@
+/*
+ * 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 android.text.format.DateFormat;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+public final class DateToStringBenchmark extends SimpleBenchmark {
+ Date date;
+ Calendar calendar;
+ SimpleDateFormat format;
+
+ @Override
+ protected void setUp() throws Exception {
+ date = new Date(0);
+ calendar = new GregorianCalendar();
+ calendar.setTime(date);
+ format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
+ }
+
+ public void timeDateToString(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ date.toString();
+ }
+ }
+
+ public void timeDateToString_Formatter(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").format(date);
+ }
+ }
+
+ public void timeDateToString_ClonedFormatter(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ ((SimpleDateFormat) format.clone()).format(date);
+ }
+ }
+
+ public void timeDateToString_AndroidDateFormat(int reps) {
+ for (int i = 0; i < reps; i++) {
+ DateFormat.format("EEE MMM dd kk:mm:ss zzz yyyy", calendar);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ Runner.main(DateToStringBenchmark.class, args);
+ }
+}
diff --git a/benchmarks/regression/DefaultCharsetBenchmark.java b/benchmarks/regression/DefaultCharsetBenchmark.java
new file mode 100644
index 0000000..bc7b013
--- /dev/null
+++ b/benchmarks/regression/DefaultCharsetBenchmark.java
@@ -0,0 +1,29 @@
+/*
+ * 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.nio.charset.Charset;
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class DefaultCharsetBenchmark extends SimpleBenchmark {
+ public void time_defaultCharset(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ Charset.defaultCharset();
+ }
+ }
+}
diff --git a/benchmarks/regression/DigestBenchmark.java b/benchmarks/regression/DigestBenchmark.java
new file mode 100644
index 0000000..7d00fec
--- /dev/null
+++ b/benchmarks/regression/DigestBenchmark.java
@@ -0,0 +1,65 @@
+/*
+ * 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.SimpleBenchmark;
+import com.android.org.bouncycastle.crypto.Digest;
+
+public class DigestBenchmark extends SimpleBenchmark {
+
+ private static final int DATA_SIZE = 8192;
+ private static final byte[] DATA = new byte[DATA_SIZE];
+ static {
+ for (int i = 0; i < DATA_SIZE; i++) {
+ DATA[i] = (byte)i;
+ }
+ }
+
+ @Param private Algorithm algorithm;
+
+ public enum Algorithm { MD5, SHA1, SHA256, SHA384, SHA512 };
+
+ @Param private Implementation implementation;
+
+ public enum Implementation { OPENSSL, BOUNCYCASTLE };
+
+ private Class<? extends Digest> digestClass;
+
+ @Override protected void setUp() throws Exception {
+ String className = "com.android.org.bouncycastle.crypto.digests.";
+ switch (implementation) {
+ case OPENSSL:
+ className += ("OpenSSLDigest$" + algorithm);
+ break;
+ case BOUNCYCASTLE:
+ className += (algorithm + "Digest");
+ break;
+ default:
+ throw new RuntimeException(implementation.toString());
+ }
+ this.digestClass = (Class<? extends Digest>)Class.forName(className);
+ }
+
+ public void time(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ Digest digest = digestClass.newInstance();
+ digest.update(DATA, 0, DATA_SIZE);
+ digest.doFinal(new byte[digest.getDigestSize()], 0);
+ }
+ }
+}
diff --git a/benchmarks/regression/DnsBenchmark.java b/benchmarks/regression/DnsBenchmark.java
new file mode 100644
index 0000000..2a71716
--- /dev/null
+++ b/benchmarks/regression/DnsBenchmark.java
@@ -0,0 +1,51 @@
+/*
+ * 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.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class DnsBenchmark extends SimpleBenchmark {
+ public void timeDns(int reps) throws Exception {
+ String[] hosts = new String[] {
+ "www.amazon.com",
+ "z-ecx.images-amazon.com",
+ "g-ecx.images-amazon.com",
+ "ecx.images-amazon.com",
+ "ad.doubleclick.com",
+ "bpx.a9.com",
+ "d3dtik4dz1nej0.cloudfront.net",
+ "uac.advertising.com",
+ "servedby.advertising.com",
+ "view.atdmt.com",
+ "rmd.atdmt.com",
+ "spe.atdmt.com",
+ "www.google.com",
+ "www.cnn.com",
+ "bad.host.mtv.corp.google.com",
+ };
+ for (int i = 0; i < reps; ++i) {
+ try {
+ InetAddress.getByName(hosts[i % hosts.length]);
+ } catch (UnknownHostException ex) {
+ }
+ }
+ }
+}
diff --git a/benchmarks/regression/DoPrivilegedBenchmark.java b/benchmarks/regression/DoPrivilegedBenchmark.java
new file mode 100644
index 0000000..effb284
--- /dev/null
+++ b/benchmarks/regression/DoPrivilegedBenchmark.java
@@ -0,0 +1,75 @@
+/*
+ * 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.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class DoPrivilegedBenchmark extends SimpleBenchmark {
+ public void timeDirect(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ String lineSeparator = System.getProperty("line.separator");
+ }
+ }
+
+ public void timeFastAndSlow(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ String lineSeparator;
+ if (System.getSecurityManager() == null) {
+ lineSeparator = System.getProperty("line.separator");
+ } else {
+ lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("line.separator");
+ }
+ });
+ }
+ }
+ }
+
+ public void timeNewAction(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ String lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("line.separator");
+ }
+ });
+ }
+ }
+
+ public void timeReusedAction(int reps) throws Exception {
+ final PrivilegedAction<String> action = new ReusableAction("line.separator");
+ for (int i = 0; i < reps; ++i) {
+ String lineSeparator = AccessController.doPrivileged(action);
+ }
+ }
+
+ private static final class ReusableAction implements PrivilegedAction<String> {
+ private final String propertyName;
+
+ public ReusableAction(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ public String run() {
+ return System.getProperty(propertyName);
+ }
+ }
+}
diff --git a/benchmarks/regression/DoubleBenchmark.java b/benchmarks/regression/DoubleBenchmark.java
new file mode 100644
index 0000000..aa692ac
--- /dev/null
+++ b/benchmarks/regression/DoubleBenchmark.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+public class DoubleBenchmark extends SimpleBenchmark {
+ private double d = 1.2;
+ private long l = 4608083138725491507L;
+
+ public void timeDoubleToLongBits(int reps) {
+ long result = 123;
+ for (int rep = 0; rep < reps; ++rep) {
+ result = Double.doubleToLongBits(d);
+ }
+ if (result != l) {
+ throw new RuntimeException(Long.toString(result));
+ }
+ }
+
+ public void timeDoubleToRawLongBits(int reps) {
+ long result = 123;
+ for (int rep = 0; rep < reps; ++rep) {
+ result = Double.doubleToRawLongBits(d);
+ }
+ if (result != l) {
+ throw new RuntimeException(Long.toString(result));
+ }
+ }
+
+ public void timeLongBitsToDouble(int reps) {
+ double result = 123.0;
+ for (int rep = 0; rep < reps; ++rep) {
+ result = Double.longBitsToDouble(l);
+ }
+ if (result != d) {
+ throw new RuntimeException(Double.toString(result) + " " + Double.doubleToRawLongBits(result));
+ }
+ }
+}
diff --git a/benchmarks/regression/EqualsHashCodeBenchmark.java b/benchmarks/regression/EqualsHashCodeBenchmark.java
new file mode 100644
index 0000000..a15a41a
--- /dev/null
+++ b/benchmarks/regression/EqualsHashCodeBenchmark.java
@@ -0,0 +1,67 @@
+/*
+ * 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.net.URI;
+import java.net.URL;
+
+public final class EqualsHashCodeBenchmark extends SimpleBenchmark {
+ private enum Type {
+ URI() {
+ @Override Object newInstance(String text) throws Exception {
+ return new URI(text);
+ }
+ },
+ URL() {
+ @Override Object newInstance(String text) throws Exception {
+ return new URL(text);
+ }
+ };
+ abstract Object newInstance(String text) throws Exception;
+ }
+
+ @Param Type type;
+
+ Object a1;
+ Object a2;
+ Object b1;
+ Object b2;
+
+ @Override protected void setUp() throws Exception {
+ a1 = type.newInstance("https://mail.google.com/mail/u/0/?shva=1#inbox");
+ a2 = type.newInstance("https://mail.google.com/mail/u/0/?shva=1#inbox");
+ b1 = type.newInstance("http://developer.android.com/reference/java/net/URI.html");
+ b2 = type.newInstance("http://developer.android.com/reference/java/net/URI.html");
+ }
+
+ public void timeEquals(int reps) {
+ for (int i = 0; i < reps; i+=3) {
+ a1.equals(b1);
+ a1.equals(a2);
+ b1.equals(b2);
+ }
+ }
+
+ public void timeHashCode(int reps) {
+ for (int i = 0; i < reps; i+=2) {
+ a1.hashCode();
+ b1.hashCode();
+ }
+ }
+}
diff --git a/benchmarks/regression/ExpensiveObjectsBenchmark.java b/benchmarks/regression/ExpensiveObjectsBenchmark.java
new file mode 100644
index 0000000..535e298
--- /dev/null
+++ b/benchmarks/regression/ExpensiveObjectsBenchmark.java
@@ -0,0 +1,150 @@
+/*
+ * 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.Benchmark;
+import com.google.caliper.Param;
+import com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+import java.text.*;
+import java.util.*;
+
+/**
+ * Benchmarks creation and cloning various expensive objects.
+ */
+public class ExpensiveObjectsBenchmark extends SimpleBenchmark {
+ public void timeNewDateFormatTimeInstance(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
+ df.format(System.currentTimeMillis());
+ }
+ }
+
+ public void timeClonedDateFormatTimeInstance(int reps) {
+ DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
+ for (int i = 0; i < reps; ++i) {
+ ((DateFormat) df.clone()).format(System.currentTimeMillis());
+ }
+ }
+
+ public void timeReusedDateFormatTimeInstance(int reps) {
+ DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
+ for (int i = 0; i < reps; ++i) {
+ synchronized (df) {
+ df.format(System.currentTimeMillis());
+ }
+ }
+ }
+
+ public void timeNewCollator(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ Collator.getInstance(Locale.US);
+ }
+ }
+
+ public void timeClonedCollator(int reps) {
+ Collator c = Collator.getInstance(Locale.US);
+ for (int i = 0; i < reps; ++i) {
+ c.clone();
+ }
+ }
+
+ public void timeNewDateFormatSymbols(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ new DateFormatSymbols(Locale.US);
+ }
+ }
+
+ public void timeClonedDateFormatSymbols(int reps) {
+ DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
+ for (int i = 0; i < reps; ++i) {
+ dfs.clone();
+ }
+ }
+
+ public void timeNewDecimalFormatSymbols(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ new DecimalFormatSymbols(Locale.US);
+ }
+ }
+
+ public void timeClonedDecimalFormatSymbols(int reps) {
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+ for (int i = 0; i < reps; ++i) {
+ dfs.clone();
+ }
+ }
+
+ public void timeNewNumberFormat(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ NumberFormat.getInstance(Locale.US);
+ }
+ }
+
+ public void timeClonedNumberFormat(int reps) {
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ for (int i = 0; i < reps; ++i) {
+ nf.clone();
+ }
+ }
+
+ public void timeNumberFormatTrivialFormatLong(int reps) {
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ for (int i = 0; i < reps; ++i) {
+ nf.format(1024L);
+ }
+ }
+
+ public void timeLongToString(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ Long.toString(1024L);
+ }
+ }
+
+ public void timeNumberFormatTrivialFormatDouble(int reps) {
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ for (int i = 0; i < reps; ++i) {
+ nf.format(1024.0);
+ }
+ }
+
+ public void timeNewSimpleDateFormat(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ new SimpleDateFormat();
+ }
+ }
+
+ public void timeClonedSimpleDateFormat(int reps) {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ for (int i = 0; i < reps; ++i) {
+ sdf.clone();
+ }
+ }
+
+ public void timeNewGregorianCalendar(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ new GregorianCalendar();
+ }
+ }
+
+ public void timeClonedGregorianCalendar(int reps) {
+ GregorianCalendar gc = new GregorianCalendar();
+ for (int i = 0; i < reps; ++i) {
+ gc.clone();
+ }
+ }
+}
diff --git a/benchmarks/regression/FloatBenchmark.java b/benchmarks/regression/FloatBenchmark.java
new file mode 100644
index 0000000..a92bb69
--- /dev/null
+++ b/benchmarks/regression/FloatBenchmark.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+public class FloatBenchmark extends SimpleBenchmark {
+ private float f = 1.2f;
+ private int i = 1067030938;
+
+ public void timeFloatToIntBits(int reps) {
+ int result = 123;
+ for (int rep = 0; rep < reps; ++rep) {
+ result = Float.floatToIntBits(f);
+ }
+ if (result != i) {
+ throw new RuntimeException(Integer.toString(result));
+ }
+ }
+
+ public void timeFloatToRawIntBits(int reps) {
+ int result = 123;
+ for (int rep = 0; rep < reps; ++rep) {
+ result = Float.floatToRawIntBits(f);
+ }
+ if (result != i) {
+ throw new RuntimeException(Integer.toString(result));
+ }
+ }
+
+ public void timeIntBitsToFloat(int reps) {
+ float result = 123.0f;
+ for (int rep = 0; rep < reps; ++rep) {
+ result = Float.intBitsToFloat(i);
+ }
+ if (result != f) {
+ throw new RuntimeException(Float.toString(result) + " " + Float.floatToRawIntBits(result));
+ }
+ }
+}
diff --git a/benchmarks/regression/FormatterBenchmark.java b/benchmarks/regression/FormatterBenchmark.java
new file mode 100644
index 0000000..0d4cf26
--- /dev/null
+++ b/benchmarks/regression/FormatterBenchmark.java
@@ -0,0 +1,133 @@
+/*
+ * 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.Runner;
+import com.google.caliper.SimpleBenchmark;
+import java.util.Formatter;
+import java.util.Locale;
+
+/**
+ * Compares Formatter against hand-written StringBuilder code.
+ */
+public class FormatterBenchmark extends SimpleBenchmark {
+ public void timeFormatter_NoFormatting(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Formatter f = new Formatter();
+ f.format("this is a reasonably short string that doesn't actually need any formatting");
+ }
+ }
+
+ public void timeStringBuilder_NoFormatting(int reps) {
+ for (int i = 0; i < reps; i++) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("this is a reasonably short string that doesn't actually need any formatting");
+ }
+ }
+
+ public void timeFormatter_OneInt(int reps) {
+ Integer value = Integer.valueOf(1024); // We're not trying to benchmark boxing here.
+ for (int i = 0; i < reps; i++) {
+ Formatter f = new Formatter();
+ f.format("this is a reasonably short string that has an int %d in it", value);
+ }
+ }
+
+ public void timeFormatter_OneIntArabic(int reps) {
+ Locale arabic = new Locale("ar");
+ Integer value = Integer.valueOf(1024); // We're not trying to benchmark boxing here.
+ for (int i = 0; i < reps; i++) {
+ Formatter f = new Formatter();
+ f.format(arabic, "this is a reasonably short string that has an int %d in it", value);
+ }
+ }
+
+ public void timeStringBuilder_OneInt(int reps) {
+ for (int i = 0; i < reps; i++) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("this is a reasonably short string that has an int ");
+ sb.append(1024);
+ sb.append(" in it");
+ }
+ }
+
+ public void timeFormatter_OneHexInt(int reps) {
+ Integer value = Integer.valueOf(1024); // We're not trying to benchmark boxing here.
+ for (int i = 0; i < reps; i++) {
+ Formatter f = new Formatter();
+ f.format("this is a reasonably short string that has an int %x in it", value);
+ }
+ }
+
+ public void timeStringBuilder_OneHexInt(int reps) {
+ for (int i = 0; i < reps; i++) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("this is a reasonably short string that has an int ");
+ sb.append(Integer.toHexString(1024));
+ sb.append(" in it");
+ }
+ }
+
+ public void timeFormatter_OneFloat(int reps) {
+ Float value = Float.valueOf(10.24f); // We're not trying to benchmark boxing here.
+ for (int i = 0; i < reps; i++) {
+ Formatter f = new Formatter();
+ f.format("this is a reasonably short string that has a float %f in it", value);
+ }
+ }
+
+ public void timeFormatter_OneFloat_dot2f(int reps) {
+ Float value = Float.valueOf(10.24f); // We're not trying to benchmark boxing here.
+ for (int i = 0; i < reps; i++) {
+ Formatter f = new Formatter();
+ f.format("this is a reasonably short string that has a float %.2f in it", value);
+ }
+ }
+
+ public void timeFormatter_TwoFloats(int reps) {
+ Float value = Float.valueOf(10.24f); // We're not trying to benchmark boxing here.
+ for (int i = 0; i < reps; i++) {
+ Formatter f = new Formatter();
+ f.format("this is a reasonably short string that has two floats %f and %f in it", value, value);
+ }
+ }
+
+ public void timeStringBuilder_OneFloat(int reps) {
+ for (int i = 0; i < reps; i++) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("this is a reasonably short string that has a float ");
+ sb.append(10.24f);
+ sb.append(" in it");
+ }
+ }
+
+ public void timeFormatter_OneString(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Formatter f = new Formatter();
+ f.format("this is a reasonably short string that has a string %s in it", "hello");
+ }
+ }
+
+ public void timeStringBuilder_OneString(int reps) {
+ for (int i = 0; i < reps; i++) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("this is a reasonably short string that has a string ");
+ sb.append("hello");
+ sb.append(" in it");
+ }
+ }
+}
diff --git a/benchmarks/regression/HostnameVerifierBenchmark.java b/benchmarks/regression/HostnameVerifierBenchmark.java
new file mode 100644
index 0000000..e9218c4
--- /dev/null
+++ b/benchmarks/regression/HostnameVerifierBenchmark.java
@@ -0,0 +1,170 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.net.URL;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+
+/**
+ * This benchmark makes a real HTTP connection to a handful of hosts and
+ * captures the served certificates as a byte array. It then verifies each
+ * certificate in the benchmark loop, being careful to convert from the
+ * byte[] to the certificate each time. Otherwise the certificate class
+ * caches previous results which skews the results of the benchmark: In practice
+ * each certificate instance is verified once and then released.
+ */
+public final class HostnameVerifierBenchmark extends SimpleBenchmark {
+
+ @Param({"android.clients.google.com",
+ "m.google.com",
+ "www.google.com",
+ "www.amazon.com",
+ "www.ubs.com"}) String host;
+
+ private String hostname;
+ private HostnameVerifier hostnameVerifier;
+ private byte[][] encodedCertificates;
+
+ @Override protected void setUp() throws Exception {
+ URL url = new URL("https", host, "/");
+ hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+ HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+ connection.setHostnameVerifier(new HostnameVerifier() {
+ public boolean verify(String hostname, SSLSession sslSession) {
+ try {
+ encodedCertificates = certificatesToBytes(sslSession.getPeerCertificates());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ HostnameVerifierBenchmark.this.hostname = hostname;
+ return true;
+ }
+ });
+ connection.getInputStream();
+ connection.disconnect();
+ }
+
+ public void timeVerify(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ final Certificate[] certificates = bytesToCertificates(encodedCertificates);
+ FakeSSLSession sslSession = new FakeSSLSession() {
+ @Override public Certificate[] getPeerCertificates() {
+ return certificates;
+ }
+ };
+ hostnameVerifier.verify(hostname, sslSession);
+ }
+ }
+
+ private byte[][] certificatesToBytes(Certificate[] certificates) throws Exception {
+ byte[][] result = new byte[certificates.length][];
+ for (int i = 0, certificatesLength = certificates.length; i < certificatesLength; i++) {
+ result[i] = certificates[i].getEncoded();
+ }
+ return result;
+ }
+
+ private Certificate[] bytesToCertificates(byte[][] encodedCertificates) throws Exception {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+ Certificate[] result = new Certificate[encodedCertificates.length];
+ for (int i = 0; i < encodedCertificates.length; i++) {
+ result[i] = certificateFactory.generateCertificate(
+ new ByteArrayInputStream(encodedCertificates[i]));
+ }
+ return result;
+ }
+
+ private static class FakeSSLSession implements SSLSession {
+ public int getApplicationBufferSize() {
+ throw new UnsupportedOperationException();
+ }
+ public String getCipherSuite() {
+ throw new UnsupportedOperationException();
+ }
+ public long getCreationTime() {
+ throw new UnsupportedOperationException();
+ }
+ public byte[] getId() {
+ throw new UnsupportedOperationException();
+ }
+ public long getLastAccessedTime() {
+ throw new UnsupportedOperationException();
+ }
+ public Certificate[] getLocalCertificates() {
+ throw new UnsupportedOperationException();
+ }
+ public Principal getLocalPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+ public int getPacketBufferSize() {
+ throw new UnsupportedOperationException();
+ }
+ public javax.security.cert.X509Certificate[] getPeerCertificateChain() {
+ throw new UnsupportedOperationException();
+ }
+ public Certificate[] getPeerCertificates() {
+ throw new UnsupportedOperationException();
+ }
+ public String getPeerHost() {
+ throw new UnsupportedOperationException();
+ }
+ public int getPeerPort() {
+ throw new UnsupportedOperationException();
+ }
+ public Principal getPeerPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+ public String getProtocol() {
+ throw new UnsupportedOperationException();
+ }
+ public SSLSessionContext getSessionContext() {
+ throw new UnsupportedOperationException();
+ }
+ public Object getValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+ public String[] getValueNames() {
+ throw new UnsupportedOperationException();
+ }
+ public void invalidate() {
+ throw new UnsupportedOperationException();
+ }
+ public boolean isValid() {
+ throw new UnsupportedOperationException();
+ }
+ public void putValue(String name, Object value) {
+ throw new UnsupportedOperationException();
+ }
+ public void removeValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public static void main(String[] args) {
+ Runner.main(HostnameVerifierBenchmark.class, args);
+ }
+}
diff --git a/benchmarks/regression/IntConstantDivisionBenchmark.java b/benchmarks/regression/IntConstantDivisionBenchmark.java
new file mode 100644
index 0000000..498b783
--- /dev/null
+++ b/benchmarks/regression/IntConstantDivisionBenchmark.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+public class IntConstantDivisionBenchmark extends SimpleBenchmark {
+ public int timeDivideIntByConstant2(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result /= 2;
+ }
+ return result;
+ }
+ public int timeDivideIntByConstant8(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result /= 8;
+ }
+ return result;
+ }
+ public int timeDivideIntByConstant10(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result /= 10;
+ }
+ return result;
+ }
+ public int timeDivideIntByConstant100(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result /= 100;
+ }
+ return result;
+ }
+ public int timeDivideIntByConstant100_HandOptimized(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result = (int) ((0x51eb851fL * result) >>> 37);
+ }
+ return result;
+ }
+ public int timeDivideIntByConstant2048(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result /= 2048;
+ }
+ return result;
+ }
+ public int timeDivideIntByVariable2(int reps) {
+ int result = 1;
+ int factor = 2;
+ for (int i = 0; i < reps; ++i) {
+ result /= factor;
+ }
+ return result;
+ }
+ public int timeDivideIntByVariable10(int reps) {
+ int result = 1;
+ int factor = 10;
+ for (int i = 0; i < reps; ++i) {
+ result /= factor;
+ }
+ return result;
+ }
+}
diff --git a/benchmarks/regression/IntConstantMultiplicationBenchmark.java b/benchmarks/regression/IntConstantMultiplicationBenchmark.java
new file mode 100644
index 0000000..ca1349c
--- /dev/null
+++ b/benchmarks/regression/IntConstantMultiplicationBenchmark.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+public class IntConstantMultiplicationBenchmark extends SimpleBenchmark {
+ public int timeMultiplyIntByConstant6(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result *= 6;
+ }
+ return result;
+ }
+ public int timeMultiplyIntByConstant7(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result *= 7;
+ }
+ return result;
+ }
+ public int timeMultiplyIntByConstant8(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result *= 8;
+ }
+ return result;
+ }
+ public int timeMultiplyIntByConstant8_Shift(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result <<= 3;
+ }
+ return result;
+ }
+ public int timeMultiplyIntByConstant10(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result *= 10;
+ }
+ return result;
+ }
+ public int timeMultiplyIntByConstant10_Shift(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result = (result + (result << 2)) << 1;
+ }
+ return result;
+ }
+ public int timeMultiplyIntByConstant2047(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result *= 2047;
+ }
+ return result;
+ }
+ public int timeMultiplyIntByConstant2048(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result *= 2048;
+ }
+ return result;
+ }
+ public int timeMultiplyIntByConstant2049(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result *= 2049;
+ }
+ 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;
+ }
+}
diff --git a/benchmarks/regression/IntConstantRemainderBenchmark.java b/benchmarks/regression/IntConstantRemainderBenchmark.java
new file mode 100644
index 0000000..6174721
--- /dev/null
+++ b/benchmarks/regression/IntConstantRemainderBenchmark.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+public class IntConstantRemainderBenchmark extends SimpleBenchmark {
+ public int timeRemainderIntByConstant2(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result %= 2;
+ }
+ return result;
+ }
+ public int timeRemainderIntByConstant8(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result %= 8;
+ }
+ return result;
+ }
+/*
+ public int timeRemainderIntByConstant10(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result %= 10;
+ }
+ return result;
+ }
+ public int timeRemainderIntByConstant100(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result %= 100;
+ }
+ return result;
+ }
+*/
+ public int timeRemainderIntByConstant2048(int reps) {
+ int result = 1;
+ for (int i = 0; i < reps; ++i) {
+ result %= 2048;
+ }
+ return result;
+ }
+ public int timeRemainderIntByVariable2(int reps) {
+ int result = 1;
+ int factor = 2;
+ for (int i = 0; i < reps; ++i) {
+ result %= factor;
+ }
+ return result;
+ }
+/*
+ public int timeRemainderIntByVariable10(int reps) {
+ int result = 1;
+ int factor = 10;
+ for (int i = 0; i < reps; ++i) {
+ result %= factor;
+ }
+ return result;
+ }
+*/
+}
diff --git a/benchmarks/regression/IntegerBenchmark.java b/benchmarks/regression/IntegerBenchmark.java
new file mode 100644
index 0000000..601bb5d
--- /dev/null
+++ b/benchmarks/regression/IntegerBenchmark.java
@@ -0,0 +1,139 @@
+/*
+ * 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;
+
+public class IntegerBenchmark extends SimpleBenchmark {
+ public int timeLongSignumBranch(int reps) {
+ int t = 0;
+ for (int i = 0; i < reps; ++i) {
+ t += signum1(-i);
+ t += signum1(0);
+ t += signum1(i);
+ }
+ return t;
+ }
+
+ public int timeLongSignumBranchFree(int reps) {
+ int t = 0;
+ for (int i = 0; i < reps; ++i) {
+ t += signum2(-i);
+ t += signum2(0);
+ t += signum2(i);
+ }
+ return t;
+ }
+
+ private static int signum1(long v) {
+ return v < 0 ? -1 : (v == 0 ? 0 : 1);
+ }
+
+ private static int signum2(long v) {
+ return ((int)(v >> 63)) | (int) (-v >>> 63); // Hacker's delight 2-7
+ }
+
+ public int timeLongBitCount_BitSet(int reps) {
+ int t = 0;
+ for (int i = 0; i < reps; ++i) {
+ t += pop((long) i);
+ }
+ return t;
+ }
+
+ private static int pop(long l) {
+ int count = popX(l & 0xffffffffL);
+ count += popX(l >>> 32);
+ return count;
+ }
+
+ private static int popX(long x) {
+ // BEGIN android-note
+ // delegate to Integer.bitCount(i); consider using native code
+ // END android-note
+ x = x - ((x >>> 1) & 0x55555555);
+ x = (x & 0x33333333) + ((x >>> 2) & 0x33333333);
+ x = (x + (x >>> 4)) & 0x0f0f0f0f;
+ x = x + (x >>> 8);
+ x = x + (x >>> 16);
+ return (int) x & 0x0000003f;
+ }
+
+ public int timeLongBitCount_2Int(int reps) {
+ int t = 0;
+ for (int i = 0; i < reps; ++i) {
+ t += pop2((long) i);
+ }
+ return t;
+ }
+
+ private static int pop2(long l) {
+ int count = Integer.bitCount((int) (l & 0xffffffffL));
+ count += Integer.bitCount((int) (l >>> 32));
+ return count;
+ }
+
+ public int timeLongBitCount_Long(int reps) {
+ int t = 0;
+ for (int i = 0; i < reps; ++i) {
+ t += Long.bitCount((long) i);
+ }
+ return t;
+ }
+
+ /**
+ * Table for Seal's algorithm for Number of Trailing Zeros. Hacker's Delight
+ * online, Figure 5-18 (http://www.hackersdelight.org/revisions.pdf)
+ * The entries whose value is -1 are never referenced.
+ */
+ private static final byte[] NTZ_TABLE = {
+ 32, 0, 1, 12, 2, 6, -1, 13, 3, -1, 7, -1, -1, -1, -1, 14,
+ 10, 4, -1, -1, 8, -1, -1, 25, -1, -1, -1, -1, -1, 21, 27, 15,
+ 31, 11, 5, -1, -1, -1, -1, -1, 9, -1, -1, 24, -1, -1, 20, 26,
+ 30, -1, -1, -1, -1, 23, -1, 19, 29, -1, 22, 18, 28, 17, 16, -1
+ };
+
+ private static int numberOfTrailingZerosHD(int i) {
+ // Seal's algorithm - Hacker's Delight 5-18
+ i &= -i;
+ i = (i << 4) + i; // x *= 17
+ i = (i << 6) + i; // x *= 65
+ i = (i << 16) - i; // x *= 65535
+ return NTZ_TABLE[i >>> 26];
+ }
+
+ private static int numberOfTrailingZerosOL(int i) {
+ return NTZ_TABLE[((i & -i) * 0x0450FBAF) >>> 26];
+ }
+
+ public int timeNumberOfTrailingZerosHD(int reps) {
+ int t = 0;
+ for (int i = 0; i < reps; ++i) {
+ t += numberOfTrailingZerosHD(i);
+ }
+ return t;
+ }
+
+ public int timeNumberOfTrailingZerosOL(int reps) {
+ int t = 0;
+ for (int i = 0; i < reps; ++i) {
+ t += numberOfTrailingZerosOL(i);
+ }
+ return t;
+ }
+}
diff --git a/benchmarks/regression/IntegralToStringBenchmark.java b/benchmarks/regression/IntegralToStringBenchmark.java
new file mode 100644
index 0000000..cab9e98
--- /dev/null
+++ b/benchmarks/regression/IntegralToStringBenchmark.java
@@ -0,0 +1,172 @@
+/*
+ * 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;
+
+public class IntegralToStringBenchmark extends SimpleBenchmark {
+
+ private static final int SMALL = 12;
+ private static final int MEDIUM = 12345;
+ private static final int LARGE = 12345678;
+
+ public void time_IntegerToString_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(SMALL);
+ }
+ }
+
+ public void time_IntegerToString_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(MEDIUM);
+ }
+ }
+
+ public void time_IntegerToString_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(LARGE);
+ }
+ }
+
+ public void time_IntegerToString2_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(SMALL, 2);
+ }
+ }
+
+ public void time_IntegerToString2_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(MEDIUM, 2);
+ }
+ }
+
+ public void time_IntegerToString2_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(LARGE, 2);
+ }
+ }
+
+ public void time_IntegerToString10_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(SMALL, 10);
+ }
+ }
+
+ public void time_IntegerToString10_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(MEDIUM, 10);
+ }
+ }
+
+ public void time_IntegerToString10_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(LARGE, 10);
+ }
+ }
+
+ public void time_IntegerToString16_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(SMALL, 16);
+ }
+ }
+
+ public void time_IntegerToString16_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(MEDIUM, 16);
+ }
+ }
+
+ public void time_IntegerToString16_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toString(LARGE, 16);
+ }
+ }
+
+ public void time_IntegerToBinaryString_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toBinaryString(SMALL);
+ }
+ }
+
+ public void time_IntegerToBinaryString_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toBinaryString(MEDIUM);
+ }
+ }
+
+ public void time_IntegerToBinaryString_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toBinaryString(LARGE);
+ }
+ }
+
+ public void time_IntegerToHexString_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toHexString(SMALL);
+ }
+ }
+
+ public void time_IntegerToHexString_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toHexString(MEDIUM);
+ }
+ }
+
+ public void time_IntegerToHexString_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Integer.toHexString(LARGE);
+ }
+ }
+
+ public void time_StringBuilder_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ new StringBuilder().append(SMALL);
+ }
+ }
+
+ public void time_StringBuilder_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ new StringBuilder().append(MEDIUM);
+ }
+ }
+
+ public void time_StringBuilder_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ new StringBuilder().append(LARGE);
+ }
+ }
+
+ public void time_Formatter_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%d", SMALL);
+ }
+ }
+
+ public void time_Formatter_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%d", MEDIUM);
+ }
+ }
+
+ public void time_Formatter_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%d", LARGE);
+ }
+ }
+}
diff --git a/benchmarks/regression/JarFileBenchmark.java b/benchmarks/regression/JarFileBenchmark.java
new file mode 100644
index 0000000..626ca21
--- /dev/null
+++ b/benchmarks/regression/JarFileBenchmark.java
@@ -0,0 +1,40 @@
+/*
+ * 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.io.File;
+import java.util.jar.*;
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class JarFileBenchmark extends SimpleBenchmark {
+ @Param({
+ "/system/framework/bouncycastle.jar",
+ "/system/framework/core.jar",
+ "/system/framework/framework.jar"
+ })
+ private String filename;
+
+ public void time(int reps) throws Exception {
+ File f = new File(filename);
+ for (int i = 0; i < reps; ++i) {
+ JarFile jf = new JarFile(f);
+ Manifest m = jf.getManifest();
+ jf.close();
+ }
+ }
+}
diff --git a/benchmarks/regression/KeyPairGeneratorBenchmark.java b/benchmarks/regression/KeyPairGeneratorBenchmark.java
new file mode 100644
index 0000000..762c935
--- /dev/null
+++ b/benchmarks/regression/KeyPairGeneratorBenchmark.java
@@ -0,0 +1,65 @@
+/*
+ * 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.SimpleBenchmark;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.KeyPairGenerator;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+
+public class KeyPairGeneratorBenchmark extends SimpleBenchmark {
+ @Param private Algorithm algorithm;
+
+ public enum Algorithm {
+ RSA,
+ DSA,
+ };
+
+ @Param private Implementation implementation;
+
+ public enum Implementation { OpenSSL, BouncyCastle };
+
+ private String generatorAlgorithm;
+ private KeyPairGenerator generator;
+ private SecureRandom random;
+
+ @Override protected void setUp() throws Exception {
+ this.generatorAlgorithm = algorithm.toString();
+
+ final String provider;
+ if (implementation == Implementation.BouncyCastle) {
+ provider = "BC";
+ } else {
+ provider = "AndroidOpenSSL";
+ }
+
+ this.generator = KeyPairGenerator.getInstance(generatorAlgorithm, provider);
+ this.random = SecureRandom.getInstance("SHA1PRNG");
+ this.generator.initialize(1024);
+ }
+
+ public void time(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ KeyPair keyPair = generator.generateKeyPair();
+ }
+ }
+}
diff --git a/benchmarks/regression/LoopingBackwardsBenchmark.java b/benchmarks/regression/LoopingBackwardsBenchmark.java
new file mode 100644
index 0000000..054eff9
--- /dev/null
+++ b/benchmarks/regression/LoopingBackwardsBenchmark.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+/**
+ * Testing the old canard that looping backwards is faster.
+ *
+ * @author Kevin Bourrillion
+ */
+public class LoopingBackwardsBenchmark extends SimpleBenchmark {
+ @Param({"2", "20", "2000", "20000000"}) int max;
+
+ public int timeForwards(int reps) {
+ int dummy = 0;
+ for (int i = 0; i < reps; i++) {
+ for (int j = 0; j < max; j++) {
+ dummy += j;
+ }
+ }
+ return dummy;
+ }
+
+ public int timeBackwards(int reps) {
+ int dummy = 0;
+ for (int i = 0; i < reps; i++) {
+ for (int j = max - 1; j >= 0; j--) {
+ dummy += j;
+ }
+ }
+ return dummy;
+ }
+}
diff --git a/benchmarks/regression/MathBenchmark.java b/benchmarks/regression/MathBenchmark.java
new file mode 100644
index 0000000..25a871d
--- /dev/null
+++ b/benchmarks/regression/MathBenchmark.java
@@ -0,0 +1,368 @@
+/*
+ * 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;
+
+/**
+ * Many of these tests are bogus in that the cost will vary wildly depending on inputs.
+ * For _my_ current purposes, that's okay. But beware!
+ */
+public class MathBenchmark extends SimpleBenchmark {
+ private final double d = 1.2;
+ private final float f = 1.2f;
+ private final int i = 1;
+ private final long l = 1L;
+
+ public void timeAbsD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.abs(d);
+ }
+ }
+
+ public void timeAbsF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.abs(f);
+ }
+ }
+
+ public void timeAbsI(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.abs(i);
+ }
+ }
+
+ public void timeAbsL(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.abs(l);
+ }
+ }
+
+ public void timeAcos(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.acos(d);
+ }
+ }
+
+ public void timeAsin(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.asin(d);
+ }
+ }
+
+ public void timeAtan(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.atan(d);
+ }
+ }
+
+ public void timeAtan2(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.atan2(3, 4);
+ }
+ }
+
+ public void timeCbrt(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.cbrt(d);
+ }
+ }
+
+ public void timeCeil(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.ceil(d);
+ }
+ }
+
+ public void timeCopySignD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.copySign(d, d);
+ }
+ }
+
+ public void timeCopySignF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.copySign(f, f);
+ }
+ }
+
+ public void timeCopySignD_strict(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.copySign(d, d);
+ }
+ }
+
+ public void timeCopySignF_strict(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.copySign(f, f);
+ }
+ }
+
+ public void timeCos(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.cos(d);
+ }
+ }
+
+ public void timeCosh(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.cosh(d);
+ }
+ }
+
+ public void timeExp(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.exp(d);
+ }
+ }
+
+ public void timeExpm1(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.expm1(d);
+ }
+ }
+
+ public void timeFloor(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.floor(d);
+ }
+ }
+
+ public void timeGetExponentD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.getExponent(d);
+ }
+ }
+
+ public void timeGetExponentF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.getExponent(f);
+ }
+ }
+
+ public void timeHypot(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.hypot(d, d);
+ }
+ }
+
+ public void timeIEEEremainder(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.IEEEremainder(d, d);
+ }
+ }
+
+ public void timeLog(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.log(d);
+ }
+ }
+
+ public void timeLog10(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.log10(d);
+ }
+ }
+
+ public void timeLog1p(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.log1p(d);
+ }
+ }
+
+ public void timeMaxD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.max(d, d);
+ }
+ }
+
+ public void timeMaxF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.max(f, f);
+ }
+ }
+
+ public void timeMaxI(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.max(i, i);
+ }
+ }
+
+ public void timeMaxL(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.max(l, l);
+ }
+ }
+
+ public void timeMinD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.min(d, d);
+ }
+ }
+
+ public void timeMinF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.min(f, f);
+ }
+ }
+
+ public void timeMinI(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.min(i, i);
+ }
+ }
+
+ public void timeMinL(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.min(l, l);
+ }
+ }
+
+ public void timeNextAfterD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.nextAfter(d, d);
+ }
+ }
+
+ public void timeNextAfterF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.nextAfter(f, f);
+ }
+ }
+
+ public void timeNextUpD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.nextUp(d);
+ }
+ }
+
+ public void timeNextUpF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.nextUp(f);
+ }
+ }
+
+ public void timePow(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.pow(d, d);
+ }
+ }
+
+ public void timeRandom(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.random();
+ }
+ }
+
+ public void timeRint(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.rint(d);
+ }
+ }
+
+ public void timeRoundD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.round(d);
+ }
+ }
+
+ public void timeRoundF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.round(f);
+ }
+ }
+
+ public void timeScalbD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.scalb(d, 5);
+ }
+ }
+
+ public void timeScalbF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.scalb(f, 5);
+ }
+ }
+
+ public void timeSignumD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.signum(d);
+ }
+ }
+
+ public void timeSignumF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.signum(f);
+ }
+ }
+
+ public void timeSin(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.sin(d);
+ }
+ }
+
+ public void timeSinh(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.sinh(d);
+ }
+ }
+
+ public void timeSqrt(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.sqrt(d);
+ }
+ }
+
+ public void timeTan(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.tan(d);
+ }
+ }
+
+ public void timeTanh(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.tanh(d);
+ }
+ }
+
+ public void timeToDegrees(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.toDegrees(d);
+ }
+ }
+
+ public void timeToRadians(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.toRadians(d);
+ }
+ }
+
+ public void timeUlpD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.ulp(d);
+ }
+ }
+
+ public void timeUlpF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Math.ulp(f);
+ }
+ }
+}
diff --git a/benchmarks/regression/MessageDigestBenchmark.java b/benchmarks/regression/MessageDigestBenchmark.java
new file mode 100644
index 0000000..c9d8074
--- /dev/null
+++ b/benchmarks/regression/MessageDigestBenchmark.java
@@ -0,0 +1,49 @@
+/*
+ * 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.SimpleBenchmark;
+import java.security.MessageDigest;
+
+public class MessageDigestBenchmark extends SimpleBenchmark {
+
+ private static final int DATA_SIZE = 8192;
+ private static final byte[] DATA = new byte[DATA_SIZE];
+ static {
+ for (int i = 0; i < DATA_SIZE; i++) {
+ DATA[i] = (byte)i;
+ }
+ }
+
+ @Param private Algorithm algorithm;
+
+ public enum Algorithm { MD5, SHA1, SHA256, SHA384, SHA512 };
+
+ @Param private Provider provider;
+
+ public enum Provider { AndroidOpenSSL, BC };
+
+ public void time(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ MessageDigest digest = MessageDigest.getInstance(algorithm.toString(),
+ provider.toString());
+ digest.update(DATA, 0, DATA_SIZE);
+ digest.digest();
+ }
+ }
+}
diff --git a/benchmarks/regression/MutableIntBenchmark.java b/benchmarks/regression/MutableIntBenchmark.java
new file mode 100644
index 0000000..ee4f2d9
--- /dev/null
+++ b/benchmarks/regression/MutableIntBenchmark.java
@@ -0,0 +1,92 @@
+/*
+ * 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.util.concurrent.atomic.AtomicInteger;
+
+public final class MutableIntBenchmark extends SimpleBenchmark {
+
+ enum Kind {
+ ARRAY() {
+ int[] value = new int[1];
+
+ @Override void timeCreate(int reps) {
+ for (int i = 0; i < reps; i++) {
+ value = new int[] { 5 };
+ }
+ }
+ @Override void timeIncrement(int reps) {
+ for (int i = 0; i < reps; i++) {
+ value[0]++;
+ }
+ }
+ @Override int timeGet(int reps) {
+ int sum = 0;
+ for (int i = 0; i < reps; i++) {
+ sum += value[0];
+ }
+ return sum;
+ }
+ },
+ ATOMIC() {
+ AtomicInteger value = new AtomicInteger();
+
+ @Override void timeCreate(int reps) {
+ for (int i = 0; i < reps; i++) {
+ value = new AtomicInteger(5);
+ }
+ }
+ @Override void timeIncrement(int reps) {
+ for (int i = 0; i < reps; i++) {
+ value.incrementAndGet();
+ }
+ }
+ @Override int timeGet(int reps) {
+ int sum = 0;
+ for (int i = 0; i < reps; i++) {
+ sum += value.intValue();
+ }
+ return sum;
+ }
+ };
+
+ abstract void timeCreate(int reps);
+ abstract void timeIncrement(int reps);
+ abstract int timeGet(int reps);
+ }
+
+ @Param Kind kind;
+
+ public void timeCreate(int reps) {
+ kind.timeCreate(reps);
+ }
+
+ public void timeIncrement(int reps) {
+ kind.timeIncrement(reps);
+ }
+
+ public void timeGet(int reps) {
+ kind.timeGet(reps);
+ }
+
+ public static void main(String[] args) {
+ Runner.main(MutableIntBenchmark.class, args);
+ }
+}
diff --git a/benchmarks/regression/NativeMethodBenchmark.java b/benchmarks/regression/NativeMethodBenchmark.java
new file mode 100644
index 0000000..2e482ef
--- /dev/null
+++ b/benchmarks/regression/NativeMethodBenchmark.java
@@ -0,0 +1,79 @@
+/*
+ * 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.SimpleBenchmark;
+import org.apache.harmony.dalvik.NativeTestTarget;
+
+public class NativeMethodBenchmark extends SimpleBenchmark {
+ public void time_emptyJniStaticSynchronizedMethod0(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ NativeTestTarget.emptyJniStaticSynchronizedMethod0();
+ }
+ }
+
+ public void time_emptyJniSynchronizedMethod0(int reps) throws Exception {
+ NativeTestTarget n = new NativeTestTarget();
+ for (int i = 0; i < reps; ++i) {
+ n.emptyJniSynchronizedMethod0();
+ }
+ }
+
+ public void time_emptyJniStaticMethod0(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ NativeTestTarget.emptyJniStaticMethod0();
+ }
+ }
+
+ public void time_emptyJniMethod0(int reps) throws Exception {
+ NativeTestTarget n = new NativeTestTarget();
+ for (int i = 0; i < reps; ++i) {
+ n.emptyJniMethod0();
+ }
+ }
+
+ public void time_emptyJniStaticMethod6(int reps) throws Exception {
+ int a = -1;
+ int b = 0;
+ for (int i = 0; i < reps; ++i) {
+ NativeTestTarget.emptyJniStaticMethod6(a, b, 1, 2, 3, i);
+ }
+ }
+
+ public void time_emptyJniMethod6(int reps) throws Exception {
+ int a = -1;
+ int b = 0;
+ NativeTestTarget n = new NativeTestTarget();
+ for (int i = 0; i < reps; ++i) {
+ n.emptyJniMethod6(a, b, 1, 2, 3, i);
+ }
+ }
+
+ public void time_emptyJniStaticMethod6L(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ NativeTestTarget.emptyJniStaticMethod6L(null, null, null, null, null, null);
+ }
+ }
+
+ public void time_emptyJniMethod6L(int reps) throws Exception {
+ NativeTestTarget n = new NativeTestTarget();
+ for (int i = 0; i < reps; ++i) {
+ n.emptyJniMethod6L(null, null, null, null, null, null);
+ }
+ }
+
+}
diff --git a/benchmarks/regression/ParseBenchmark.java b/benchmarks/regression/ParseBenchmark.java
new file mode 100644
index 0000000..b44b429
--- /dev/null
+++ b/benchmarks/regression/ParseBenchmark.java
@@ -0,0 +1,217 @@
+/*
+ * 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.Runner;
+import com.google.caliper.SimpleBenchmark;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParserFactory;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * Measure throughput of various parsers.
+ *
+ * <p>This benchmark requires that ParseBenchmarkData.zip is on the classpath.
+ * That file contains Twitter feed data, which is representative of what
+ * applications will be parsing.
+ */
+public final class ParseBenchmark extends SimpleBenchmark {
+
+ @Param Document document;
+ @Param Api api;
+
+ private enum Document {
+ TWEETS,
+ READER_SHORT,
+ READER_LONG
+ }
+
+ private enum Api {
+ ANDROID_STREAM("json") {
+ @Override Parser newParser() {
+ return new AndroidStreamParser();
+ }
+ },
+ ORG_JSON("json") {
+ @Override Parser newParser() {
+ return new OrgJsonParser();
+ }
+ },
+ XML_PULL("xml") {
+ @Override Parser newParser() {
+ return new GeneralXmlPullParser();
+ }
+ },
+ XML_DOM("xml") {
+ @Override Parser newParser() {
+ return new XmlDomParser();
+ }
+ },
+ XML_SAX("xml") {
+ @Override Parser newParser() {
+ return new XmlSaxParser();
+ }
+ };
+
+ final String extension;
+
+ private Api(String extension) {
+ this.extension = extension;
+ }
+
+ abstract Parser newParser();
+ }
+
+ private String text;
+ private Parser parser;
+
+ @Override protected void setUp() throws Exception {
+ text = resourceToString("/" + document.name() + "." + api.extension);
+ parser = api.newParser();
+ }
+
+ public void timeParse(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ parser.parse(text);
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ Runner.main(ParseBenchmark.class, args);
+ }
+
+ private static String resourceToString(String path) throws Exception {
+ InputStream in = ParseBenchmark.class.getResourceAsStream(path);
+ if (in == null) {
+ throw new IllegalArgumentException("No such file: " + path);
+ }
+
+ Reader reader = new InputStreamReader(in, "UTF-8");
+ char[] buffer = new char[8192];
+ StringWriter writer = new StringWriter();
+ int count;
+ while ((count = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, count);
+ }
+ reader.close();
+ return writer.toString();
+ }
+
+ interface Parser {
+ void parse(String data) throws Exception;
+ }
+
+ private static class AndroidStreamParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ android.util.JsonReader jsonReader
+ = new android.util.JsonReader(new StringReader(data));
+ readToken(jsonReader);
+ jsonReader.close();
+ }
+
+ public void readObject(android.util.JsonReader reader) throws IOException {
+ reader.beginObject();
+ while (reader.hasNext()) {
+ reader.nextName();
+ readToken(reader);
+ }
+ reader.endObject();
+ }
+
+ public void readArray(android.util.JsonReader reader) throws IOException {
+ reader.beginArray();
+ while (reader.hasNext()) {
+ readToken(reader);
+ }
+ reader.endArray();
+ }
+
+ private void readToken(android.util.JsonReader reader) throws IOException {
+ switch (reader.peek()) {
+ case BEGIN_ARRAY:
+ readArray(reader);
+ break;
+ case BEGIN_OBJECT:
+ readObject(reader);
+ break;
+ case BOOLEAN:
+ reader.nextBoolean();
+ break;
+ case NULL:
+ reader.nextNull();
+ break;
+ case NUMBER:
+ reader.nextLong();
+ break;
+ case STRING:
+ reader.nextString();
+ break;
+ default:
+ throw new IllegalArgumentException("Unexpected token" + reader.peek());
+ }
+ }
+ }
+
+ private static class OrgJsonParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ if (data.startsWith("[")) {
+ new JSONArray(data);
+ } else if (data.startsWith("{")) {
+ new JSONObject(data);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ private static class GeneralXmlPullParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ XmlPullParser xmlParser = android.util.Xml.newPullParser();
+ xmlParser.setInput(new StringReader(data));
+ xmlParser.nextTag();
+ while (xmlParser.next() != XmlPullParser.END_DOCUMENT) {
+ xmlParser.getName();
+ xmlParser.getText();
+ }
+ }
+ }
+
+ private static class XmlDomParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ DocumentBuilderFactory.newInstance().newDocumentBuilder()
+ .parse(new InputSource(new StringReader(data)));
+ }
+ }
+
+ private static class XmlSaxParser implements Parser {
+ @Override public void parse(String data) throws Exception {
+ SAXParserFactory.newInstance().newSAXParser().parse(
+ new InputSource(new StringReader(data)), new DefaultHandler());
+ }
+ }
+}
diff --git a/benchmarks/regression/ParseBenchmarkData.zip b/benchmarks/regression/ParseBenchmarkData.zip
new file mode 100644
index 0000000..7838e8a
--- /dev/null
+++ b/benchmarks/regression/ParseBenchmarkData.zip
Binary files differ
diff --git a/benchmarks/regression/PriorityQueueBenchmark.java b/benchmarks/regression/PriorityQueueBenchmark.java
new file mode 100644
index 0000000..2fe661b
--- /dev/null
+++ b/benchmarks/regression/PriorityQueueBenchmark.java
@@ -0,0 +1,84 @@
+/*
+ * 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.SimpleBenchmark;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.PriorityQueue;
+import java.util.Random;
+
+public class PriorityQueueBenchmark extends SimpleBenchmark {
+ @Param({"100", "1000", "10000"}) private int queueSize;
+ @Param({"0", "25", "50", "75", "100"}) private int hitRate;
+
+ private PriorityQueue<Integer> pq;
+ private PriorityQueue<Integer> usepq;
+ private List<Integer> seekElements;
+ private Random random = new Random(189279387L);
+
+ @Override protected void setUp() throws Exception {
+ pq = new PriorityQueue<Integer>();
+ usepq = new PriorityQueue<Integer>();
+ seekElements = new ArrayList<Integer>();
+ List<Integer> allElements = new ArrayList<Integer>();
+ int numShared = (int)(queueSize * ((double)hitRate / 100));
+ // the total number of elements we require to engineer a hit rate of hitRate%
+ int totalElements = 2 * queueSize - numShared;
+ for (int i = 0; i < totalElements; i++) {
+ allElements.add(i);
+ }
+ // shuffle these elements so that we get a reasonable distribution of missed elements
+ Collections.shuffle(allElements, random);
+ // add shared elements
+ for (int i = 0; i < numShared; i++) {
+ pq.add(allElements.get(i));
+ seekElements.add(allElements.get(i));
+ }
+ // add priority queue only elements (these won't be touched)
+ for (int i = numShared; i < queueSize; i++) {
+ pq.add(allElements.get(i));
+ }
+ // add non-priority queue elements (these will be misses)
+ for (int i = queueSize; i < totalElements; i++) {
+ seekElements.add(allElements.get(i));
+ }
+ usepq = new PriorityQueue<Integer>(pq);
+ // shuffle again so that elements are accessed in a different pattern than they were
+ // inserted
+ Collections.shuffle(seekElements, random);
+ }
+
+ public boolean timeRemove(int reps) {
+ boolean dummy = false;
+ int elementsSize = seekElements.size();
+ // At most allow the queue to empty 10%.
+ int resizingThreshold = queueSize / 10;
+ for (int i = 0; i < reps; i++) {
+ // Reset queue every so often. This will be called more often for smaller
+ // queueSizes, but since a copy is linear, it will also cost proportionally
+ // less, and hopefully it will approximately balance out.
+ if (i % resizingThreshold == 0) {
+ usepq = new PriorityQueue<Integer>(pq);
+ }
+ dummy = usepq.remove(seekElements.get(i % elementsSize));
+ }
+ return dummy;
+ }
+}
diff --git a/benchmarks/regression/PropertyAccessBenchmark.java b/benchmarks/regression/PropertyAccessBenchmark.java
new file mode 100644
index 0000000..cabd6ed
--- /dev/null
+++ b/benchmarks/regression/PropertyAccessBenchmark.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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.SimpleBenchmark;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public final class PropertyAccessBenchmark extends SimpleBenchmark {
+ private View view = new View();
+ private Method setX;
+ private GeneratedProperty generatedSetter = new GeneratedSetter();
+ private GeneratedProperty generatedField = new GeneratedField();
+ private Field x;
+ private Object[] argsBox = new Object[1];
+
+ @Override protected void setUp() throws Exception {
+ setX = View.class.getDeclaredMethod("setX", float.class);
+ x = View.class.getDeclaredField("x");
+ }
+
+ public void timeDirectSetter(int reps) {
+ for (int i = 0; i < reps; i++) {
+ view.setX(0.1f);
+ }
+ }
+
+ public void timeDirectFieldSet(int reps) {
+ for (int i = 0; i < reps; i++) {
+ view.x = 0.1f;
+ }
+ }
+
+ public void timeDirectSetterAndBoxing(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Float value = 0.1f;
+ view.setX(value);
+ }
+ }
+
+ public void timeDirectFieldSetAndBoxing(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Float value = 0.1f;
+ view.x = value;
+ }
+ }
+
+ public void timeReflectionSetterAndTwoBoxes(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ setX.invoke(view, 0.1f);
+ }
+ }
+
+ public void timeReflectionSetterAndOneBox(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ argsBox[0] = 0.1f;
+ setX.invoke(view, argsBox);
+ }
+ }
+
+ public void timeReflectionFieldSet(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ x.setFloat(view, 0.1f);
+ }
+ }
+
+ public void timeGeneratedSetter(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ generatedSetter.setFloat(view, 0.1f);
+ }
+ }
+
+ public void timeGeneratedFieldSet(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ generatedField.setFloat(view, 0.1f);
+ }
+ }
+
+ static class View {
+ float x;
+
+ public void setX(float x) {
+ this.x = x;
+ }
+ }
+
+ static interface GeneratedProperty {
+ void setFloat(View v, float f);
+ }
+
+ static class GeneratedSetter implements GeneratedProperty {
+ public void setFloat(View v, float f) {
+ v.setX(f);
+ }
+ }
+
+ static class GeneratedField implements GeneratedProperty {
+ public void setFloat(View v, float f) {
+ v.x = f;
+ }
+ }
+}
diff --git a/benchmarks/regression/RandomBenchmark.java b/benchmarks/regression/RandomBenchmark.java
new file mode 100644
index 0000000..0792805
--- /dev/null
+++ b/benchmarks/regression/RandomBenchmark.java
@@ -0,0 +1,52 @@
+/*
+ * 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.security.SecureRandom;
+import java.util.Random;
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class RandomBenchmark extends SimpleBenchmark {
+ public void timeNewRandom(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ Random rng = new Random();
+ rng.nextInt();
+ }
+ }
+
+ public void timeReusedRandom(int reps) throws Exception {
+ Random rng = new Random();
+ for (int i = 0; i < reps; ++i) {
+ rng.nextInt();
+ }
+ }
+
+ public void timeReusedSecureRandom(int reps) throws Exception {
+ SecureRandom rng = new SecureRandom();
+ for (int i = 0; i < reps; ++i) {
+ rng.nextInt();
+ }
+ }
+
+ public void timeNewSecureRandom(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ SecureRandom rng = new SecureRandom();
+ rng.nextInt();
+ }
+ }
+}
diff --git a/benchmarks/regression/RealToStringBenchmark.java b/benchmarks/regression/RealToStringBenchmark.java
new file mode 100644
index 0000000..8914cf6
--- /dev/null
+++ b/benchmarks/regression/RealToStringBenchmark.java
@@ -0,0 +1,130 @@
+/*
+ * 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;
+
+public class RealToStringBenchmark extends SimpleBenchmark {
+
+ private static final float SMALL = -123.45f;
+ private static final float MEDIUM = -123.45e8f;
+ private static final float LARGE = -123.45e36f;
+
+ public void timeFloat_toString_NaN(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.toString(Float.NaN);
+ }
+ }
+
+ public void timeFloat_toString_NEGATIVE_INFINITY(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.toString(Float.NEGATIVE_INFINITY);
+ }
+ }
+
+ public void timeFloat_toString_POSITIVE_INFINITY(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.toString(Float.POSITIVE_INFINITY);
+ }
+ }
+
+ public void timeFloat_toString_zero(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.toString(0.0f);
+ }
+ }
+
+ public void timeFloat_toString_minusZero(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.toString(-0.0f);
+ }
+ }
+
+ public void timeFloat_toString_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.toString(SMALL);
+ }
+ }
+
+ public void timeFloat_toString_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.toString(MEDIUM);
+ }
+ }
+
+ public void timeFloat_toString_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.toString(LARGE);
+ }
+ }
+
+ public void timeStringBuilder_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ new StringBuilder().append(SMALL);
+ }
+ }
+
+ public void timeStringBuilder_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ new StringBuilder().append(MEDIUM);
+ }
+ }
+
+ public void timeStringBuilder_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ new StringBuilder().append(LARGE);
+ }
+ }
+
+ public void timeFormatter_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%f", SMALL);
+ }
+ }
+
+ public void timeFormatter_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%f", MEDIUM);
+ }
+ }
+
+ public void timeFormatter_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%f", LARGE);
+ }
+ }
+
+ public void timeFormatter_dot2f_small(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%.2f", SMALL);
+ }
+ }
+
+ public void timeFormatter_dot2f_medium(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%.2f", MEDIUM);
+ }
+ }
+
+ public void timeFormatter_dot2f_large(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ String.format("%.2f", LARGE);
+ }
+ }
+}
diff --git a/benchmarks/regression/ReflectionBenchmark.java b/benchmarks/regression/ReflectionBenchmark.java
new file mode 100644
index 0000000..fe00fa2
--- /dev/null
+++ b/benchmarks/regression/ReflectionBenchmark.java
@@ -0,0 +1,182 @@
+/*
+ * 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.lang.reflect.*;
+
+public class ReflectionBenchmark extends SimpleBenchmark {
+ public void timeObject_getClass(int reps) throws Exception {
+ C c = new C();
+ for (int rep = 0; rep < reps; ++rep) {
+ c.getClass();
+ }
+ }
+
+ public void timeClass_getField(int reps) throws Exception {
+ Class<?> klass = C.class;
+ for (int rep = 0; rep < reps; ++rep) {
+ klass.getField("f");
+ }
+ }
+
+ public void timeClass_getDeclaredField(int reps) throws Exception {
+ Class<?> klass = C.class;
+ for (int rep = 0; rep < reps; ++rep) {
+ klass.getDeclaredField("f");
+ }
+ }
+
+ public void timeClass_getConstructor(int reps) throws Exception {
+ Class<?> klass = C.class;
+ for (int rep = 0; rep < reps; ++rep) {
+ klass.getConstructor();
+ }
+ }
+
+ public void timeClass_newInstance(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Constructor constructor = klass.getConstructor();
+ for (int rep = 0; rep < reps; ++rep) {
+ constructor.newInstance();
+ }
+ }
+
+ public void timeClass_getMethod(int reps) throws Exception {
+ Class<?> klass = C.class;
+ for (int rep = 0; rep < reps; ++rep) {
+ klass.getMethod("m");
+ }
+ }
+
+ public void timeClass_getDeclaredMethod(int reps) throws Exception {
+ Class<?> klass = C.class;
+ for (int rep = 0; rep < reps; ++rep) {
+ klass.getDeclaredMethod("m");
+ }
+ }
+
+ public void timeField_setInt(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Field f = klass.getDeclaredField("f");
+ C instance = new C();
+ for (int rep = 0; rep < reps; ++rep) {
+ f.setInt(instance, 1);
+ }
+ }
+
+ public void timeField_getInt(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Field f = klass.getDeclaredField("f");
+ C instance = new C();
+ for (int rep = 0; rep < reps; ++rep) {
+ f.getInt(instance);
+ }
+ }
+
+ public void timeMethod_invokeV(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Method m = klass.getDeclaredMethod("m");
+ C instance = new C();
+ for (int rep = 0; rep < reps; ++rep) {
+ m.invoke(instance);
+ }
+ }
+
+ public void timeMethod_invokeStaticV(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Method m = klass.getDeclaredMethod("sm");
+ for (int rep = 0; rep < reps; ++rep) {
+ m.invoke(null);
+ }
+ }
+
+ public void timeMethod_invokeI(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Method m = klass.getDeclaredMethod("setField", int.class);
+ C instance = new C();
+ for (int rep = 0; rep < reps; ++rep) {
+ m.invoke(instance, 1);
+ }
+ }
+
+ public void timeMethod_invokePreBoxedI(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Method m = klass.getDeclaredMethod("setField", int.class);
+ C instance = new C();
+ Integer one = Integer.valueOf(1);
+ for (int rep = 0; rep < reps; ++rep) {
+ m.invoke(instance, one);
+ }
+ }
+
+ public void timeMethod_invokeStaticI(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Method m = klass.getDeclaredMethod("setStaticField", int.class);
+ for (int rep = 0; rep < reps; ++rep) {
+ m.invoke(null, 1);
+ }
+ }
+
+ public void timeMethod_invokeStaticPreBoxedI(int reps) throws Exception {
+ Class<?> klass = C.class;
+ Method m = klass.getDeclaredMethod("setStaticField", int.class);
+ Integer one = Integer.valueOf(1);
+ for (int rep = 0; rep < reps; ++rep) {
+ m.invoke(null, one);
+ }
+ }
+
+ public void timeRegularMethodInvocation(int reps) throws Exception {
+ C instance = new C();
+ for (int rep = 0; rep < reps; ++rep) {
+ instance.setField(1);
+ }
+ }
+
+ public void timeRegularConstructor(int reps) throws Exception {
+ for (int rep = 0; rep < reps; ++rep) {
+ new C();
+ }
+ }
+
+ public static class C {
+ public static int sf = 0;
+ public int f = 0;
+
+ public C() {
+ // A non-empty constructor so we don't get optimized away.
+ f = 1;
+ }
+
+ public void m() {
+ }
+
+ public static void sm() {
+ }
+
+ public void setField(int value) {
+ f = value;
+ }
+
+ public static void setStaticField(int value) {
+ sf = value;
+ }
+ }
+}
diff --git a/benchmarks/regression/SSLSocketBenchmark.java b/benchmarks/regression/SSLSocketBenchmark.java
new file mode 100644
index 0000000..fd72a79
--- /dev/null
+++ b/benchmarks/regression/SSLSocketBenchmark.java
@@ -0,0 +1,109 @@
+/*
+ * 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.SimpleBenchmark;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URL;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+
+public class SSLSocketBenchmark extends SimpleBenchmark {
+
+ private static final int BUFFER_SIZE = 8192;
+
+ final byte[] buffer = new byte[BUFFER_SIZE];
+
+ @Param private WebSite webSite;
+
+ public enum WebSite {
+ DOCS("https://docs.google.com"),
+ MAIL("https://mail.google.com"),
+ SITES("https://sites.google.com"),
+ WWW("https://www.google.com");
+ final InetAddress host;
+ final int port;
+ final byte[] request;
+ WebSite(String uri) {
+ try {
+ URL url = new URL(uri);
+
+ this.host = InetAddress.getByName(url.getHost());
+
+ int p = url.getPort();
+ String portString;
+ if (p == -1) {
+ this.port = 443;
+ portString = "";
+ } else {
+ this.port = p;
+ portString = ":" + port;
+ }
+
+ this.request = ("GET " + uri + " HTTP/1.0\r\n"
+ + "Host: " + host + portString + "\r\n"
+ +"\r\n").getBytes();
+
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Param private Implementation implementation;
+
+ public enum Implementation { OPENSSL, HARMONY };
+
+ private SocketFactory sf;
+
+ @Override protected void setUp() throws Exception {
+ SSLContext sslContext;
+ switch (implementation) {
+ case OPENSSL:
+ sslContext = SSLContext.getInstance("SSL", "AndroidOpenSSL");
+ break;
+ case HARMONY:
+ sslContext = SSLContext.getInstance("SSL", "HarmonyJSSE");
+ break;
+ default:
+ throw new RuntimeException(implementation.toString());
+ }
+ sslContext.init(null, null, null);
+ this.sf = sslContext.getSocketFactory();
+ }
+
+ public void time(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ Socket s = sf.createSocket(webSite.host, webSite.port);
+ OutputStream out = s.getOutputStream();
+ out.write(webSite.request);
+ InputStream in = s.getInputStream();
+ while (true) {
+ int n = in.read(buffer);
+ if (n == -1) {
+ break;
+ }
+ }
+ in.close();
+ }
+ }
+}
diff --git a/benchmarks/regression/SchemePrefixBenchmark.java b/benchmarks/regression/SchemePrefixBenchmark.java
new file mode 100644
index 0000000..d90fe29
--- /dev/null
+++ b/benchmarks/regression/SchemePrefixBenchmark.java
@@ -0,0 +1,81 @@
+/*
+ * 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.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class SchemePrefixBenchmark extends SimpleBenchmark {
+
+ enum Strategy {
+ JAVA() {
+ @Override String execute(String spec) {
+ int colon = spec.indexOf(':');
+
+ if (colon < 1) {
+ return null;
+ }
+
+ for (int i = 0; i < colon; i++) {
+ char c = spec.charAt(i);
+ if (!isValidSchemeChar(i, c)) {
+ return null;
+ }
+ }
+
+ return spec.substring(0, colon).toLowerCase(Locale.US);
+ }
+
+ private boolean isValidSchemeChar(int index, char c) {
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ return true;
+ }
+ if (index > 0 && ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.')) {
+ return true;
+ }
+ return false;
+ }
+ },
+
+ REGEX() {
+ private final Pattern pattern = Pattern.compile("^([a-zA-Z][a-zA-Z0-9+\\-.]*):");
+
+ @Override String execute(String spec) {
+ Matcher matcher = pattern.matcher(spec);
+ if (matcher.find()) {
+ return matcher.group(1).toLowerCase(Locale.US);
+ } else {
+ return null;
+ }
+ }
+ };
+
+
+ abstract String execute(String spec);
+ }
+
+ @Param Strategy strategy;
+
+ public void timeSchemePrefix(int reps) {
+ for (int i = 0; i < reps; i++) {
+ strategy.execute("http://android.com");
+ }
+ }
+}
diff --git a/benchmarks/regression/SerializationBenchmark.java b/benchmarks/regression/SerializationBenchmark.java
new file mode 100644
index 0000000..bc958eb
--- /dev/null
+++ b/benchmarks/regression/SerializationBenchmark.java
@@ -0,0 +1,217 @@
+/*
+ * 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.lang.reflect.*;
+import java.util.*;
+
+public class SerializationBenchmark extends SimpleBenchmark {
+ private static byte[] bytes(Object o) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ out.writeObject(o);
+ out.close();
+ return baos.toByteArray();
+ }
+
+ public void timeReadIntArray(int reps) throws Exception {
+ int[] intArray = new int[256];
+ readSingleObject(reps, intArray);
+ }
+
+ public void timeWriteIntArray(int reps) throws Exception {
+ int[] intArray = new int[256];
+ writeSingleObject(reps, intArray);
+ }
+ public void timeReadArrayListInteger(int reps) throws Exception {
+ ArrayList<Integer> object = new ArrayList<Integer>();
+ for (int i = 0; i < 256; ++i) {
+ object.add(i);
+ }
+ readSingleObject(reps, object);
+ }
+
+ public void timeWriteArrayListInteger(int reps) throws Exception {
+ ArrayList<Integer> object = new ArrayList<Integer>();
+ for (int i = 0; i < 256; ++i) {
+ object.add(i);
+ }
+ writeSingleObject(reps, object);
+ }
+
+ public void timeReadString(int reps) throws Exception {
+ readSingleObject(reps, "hello");
+ }
+
+ public void timeReadObjectStreamClass(int reps) throws Exception {
+ // A special case because serialization itself requires this class.
+ // (This should really be a unit test.)
+ ObjectStreamClass osc = ObjectStreamClass.lookup(String.class);
+ readSingleObject(reps, osc);
+ }
+
+ public void timeWriteString(int reps) throws Exception {
+ // String is a special case that avoids JNI.
+ writeSingleObject(reps, "hello");
+ }
+
+ public void timeWriteObjectStreamClass(int reps) throws Exception {
+ // A special case because serialization itself requires this class.
+ // (This should really be a unit test.)
+ ObjectStreamClass osc = ObjectStreamClass.lookup(String.class);
+ writeSingleObject(reps, osc);
+ }
+
+ // This is a baseline for the others.
+ public void timeWriteNoObjects(int reps) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ for (int rep = 0; rep < reps; ++rep) {
+ out.reset();
+ baos.reset();
+ }
+ out.close();
+ }
+
+ private void readSingleObject(int reps, Object object) throws Exception {
+ byte[] bytes = bytes(object);
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ for (int rep = 0; rep < reps; ++rep) {
+ ObjectInputStream in = new ObjectInputStream(bais);
+ in.readObject();
+ in.close();
+ bais.reset();
+ }
+ }
+
+ private void writeSingleObject(int reps, Object o) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ for (int rep = 0; rep < reps; ++rep) {
+ out.writeObject(o);
+ out.reset();
+ baos.reset();
+ }
+ out.close();
+ }
+
+ public void timeWriteEveryKindOfField(int reps) throws Exception {
+ writeSingleObject(reps, new LittleBitOfEverything());
+ }
+ public void timeWriteSerializableBoolean(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableBoolean());
+ }
+ public void timeWriteSerializableByte(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableByte());
+ }
+ public void timeWriteSerializableChar(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableChar());
+ }
+ public void timeWriteSerializableDouble(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableDouble());
+ }
+ public void timeWriteSerializableFloat(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableFloat());
+ }
+ public void timeWriteSerializableInt(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableInt());
+ }
+ public void timeWriteSerializableLong(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableLong());
+ }
+ public void timeWriteSerializableShort(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableShort());
+ }
+ public void timeWriteSerializableReference(int reps) throws Exception {
+ writeSingleObject(reps, new SerializableReference());
+ }
+
+ public void timeReadEveryKindOfField(int reps) throws Exception {
+ readSingleObject(reps, new LittleBitOfEverything());
+ }
+ public void timeReadSerializableBoolean(int reps) throws Exception {
+ readSingleObject(reps, new SerializableBoolean());
+ }
+ public void timeReadSerializableByte(int reps) throws Exception {
+ readSingleObject(reps, new SerializableByte());
+ }
+ public void timeReadSerializableChar(int reps) throws Exception {
+ readSingleObject(reps, new SerializableChar());
+ }
+ public void timeReadSerializableDouble(int reps) throws Exception {
+ readSingleObject(reps, new SerializableDouble());
+ }
+ public void timeReadSerializableFloat(int reps) throws Exception {
+ readSingleObject(reps, new SerializableFloat());
+ }
+ public void timeReadSerializableInt(int reps) throws Exception {
+ readSingleObject(reps, new SerializableInt());
+ }
+ public void timeReadSerializableLong(int reps) throws Exception {
+ readSingleObject(reps, new SerializableLong());
+ }
+ public void timeReadSerializableShort(int reps) throws Exception {
+ readSingleObject(reps, new SerializableShort());
+ }
+ public void timeReadSerializableReference(int reps) throws Exception {
+ readSingleObject(reps, new SerializableReference());
+ }
+
+ public static class SerializableBoolean implements Serializable {
+ boolean z;
+ }
+ public static class SerializableByte implements Serializable {
+ byte b;
+ }
+ public static class SerializableChar implements Serializable {
+ char c;
+ }
+ public static class SerializableDouble implements Serializable {
+ double d;
+ }
+ public static class SerializableFloat implements Serializable {
+ float f;
+ }
+ public static class SerializableInt implements Serializable {
+ int i;
+ }
+ public static class SerializableLong implements Serializable {
+ long j;
+ }
+ public static class SerializableShort implements Serializable {
+ short s;
+ }
+ public static class SerializableReference implements Serializable {
+ Object l;
+ }
+
+ public static class LittleBitOfEverything implements Serializable {
+ boolean z;
+ byte b;
+ char c;
+ double d;
+ float f;
+ int i;
+ long j;
+ short s;
+ Object l;
+ }
+}
diff --git a/benchmarks/regression/SignatureBenchmark.java b/benchmarks/regression/SignatureBenchmark.java
new file mode 100644
index 0000000..383dcfd
--- /dev/null
+++ b/benchmarks/regression/SignatureBenchmark.java
@@ -0,0 +1,128 @@
+/*
+ * 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.SimpleBenchmark;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.harmony.xnet.provider.jsse.OpenSSLSignature;
+
+/**
+ * Tests RSA and DSA signature creation and verification.
+ */
+public class SignatureBenchmark extends SimpleBenchmark {
+
+ private static final int DATA_SIZE = 8192;
+ private static final byte[] DATA = new byte[DATA_SIZE];
+ static {
+ for (int i = 0; i < DATA_SIZE; i++) {
+ DATA[i] = (byte)i;
+ }
+ }
+ @Param private Algorithm algorithm;
+
+ public enum Algorithm {
+ MD5WithRSA,
+ SHA1WithRSA,
+ SHA256WithRSA,
+ SHA384WithRSA,
+ SHA512WithRSA,
+ SHA1withDSA
+ };
+
+ @Param private Implementation implementation;
+
+ public enum Implementation { OpenSSL, BouncyCastle };
+
+ // Key generation and signing aren't part of the benchmark for verification
+ // so cache the results
+ private static Map<String,KeyPair> KEY_PAIRS = new HashMap<String,KeyPair>();
+ private static Map<String,byte[]> SIGNATURES = new HashMap<String,byte[]>();
+
+ private String signatureAlgorithm;
+ private byte[] signature;
+ private PrivateKey privateKey;
+ private PublicKey publicKey;
+
+ @Override protected void setUp() throws Exception {
+ this.signatureAlgorithm = algorithm.toString();
+
+ String keyAlgorithm = signatureAlgorithm.substring(signatureAlgorithm.length() - 3 ,
+ signatureAlgorithm.length());
+ KeyPair keyPair = KEY_PAIRS.get(keyAlgorithm);
+ if (keyPair == null) {
+ KeyPairGenerator generator = KeyPairGenerator.getInstance(keyAlgorithm);
+ keyPair = generator.generateKeyPair();
+ KEY_PAIRS.put(keyAlgorithm, keyPair);
+ }
+ this.privateKey = keyPair.getPrivate();
+ this.publicKey = keyPair.getPublic();
+
+ this.signature = SIGNATURES.get(signatureAlgorithm);
+ if (this.signature == null) {
+ Signature signer = Signature.getInstance(signatureAlgorithm);
+ signer.initSign(keyPair.getPrivate());
+ signer.update(DATA);
+ this.signature = signer.sign();
+ SIGNATURES.put(signatureAlgorithm, signature);
+ }
+ }
+
+ public void timeSign(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ Signature signer;
+ switch (implementation) {
+ case OpenSSL:
+ signer = Signature.getInstance(signatureAlgorithm, "AndroidOpenSSL");
+ break;
+ case BouncyCastle:
+ signer = Signature.getInstance(signatureAlgorithm, "BC");
+ break;
+ default:
+ throw new RuntimeException(implementation.toString());
+ }
+ signer.initSign(privateKey);
+ signer.update(DATA);
+ signer.sign();
+ }
+ }
+
+ public void timeVerify(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ Signature verifier;
+ switch (implementation) {
+ case OpenSSL:
+ verifier = Signature.getInstance(signatureAlgorithm, "AndroidOpenSSL");
+ break;
+ case BouncyCastle:
+ verifier = Signature.getInstance(signatureAlgorithm, "BC");
+ break;
+ default:
+ throw new RuntimeException(implementation.toString());
+ }
+ verifier.initVerify(publicKey);
+ verifier.update(DATA);
+ verifier.verify(signature);
+ }
+ }
+}
diff --git a/benchmarks/regression/StrictMathBenchmark.java b/benchmarks/regression/StrictMathBenchmark.java
new file mode 100644
index 0000000..44c030a
--- /dev/null
+++ b/benchmarks/regression/StrictMathBenchmark.java
@@ -0,0 +1,356 @@
+/*
+ * 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;
+
+/**
+ * Many of these tests are bogus in that the cost will vary wildly depending on inputs.
+ * For _my_ current purposes, that's okay. But beware!
+ */
+public class StrictMathBenchmark extends SimpleBenchmark {
+ private final double d = 1.2;
+ private final float f = 1.2f;
+ private final int i = 1;
+ private final long l = 1L;
+
+ public void timeAbsD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.abs(d);
+ }
+ }
+
+ public void timeAbsF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.abs(f);
+ }
+ }
+
+ public void timeAbsI(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.abs(i);
+ }
+ }
+
+ public void timeAbsL(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.abs(l);
+ }
+ }
+
+ public void timeAcos(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.acos(d);
+ }
+ }
+
+ public void timeAsin(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.asin(d);
+ }
+ }
+
+ public void timeAtan(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.atan(d);
+ }
+ }
+
+ public void timeAtan2(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.atan2(3, 4);
+ }
+ }
+
+ public void timeCbrt(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.cbrt(d);
+ }
+ }
+
+ public void timeCeil(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.ceil(d);
+ }
+ }
+
+ public void timeCopySignD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.copySign(d, d);
+ }
+ }
+
+ public void timeCopySignF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.copySign(f, f);
+ }
+ }
+
+ public void timeCos(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.cos(d);
+ }
+ }
+
+ public void timeCosh(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.cosh(d);
+ }
+ }
+
+ public void timeExp(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.exp(d);
+ }
+ }
+
+ public void timeExpm1(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.expm1(d);
+ }
+ }
+
+ public void timeFloor(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.floor(d);
+ }
+ }
+
+ public void timeGetExponentD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.getExponent(d);
+ }
+ }
+
+ public void timeGetExponentF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.getExponent(f);
+ }
+ }
+
+ public void timeHypot(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.hypot(d, d);
+ }
+ }
+
+ public void timeIEEEremainder(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.IEEEremainder(d, d);
+ }
+ }
+
+ public void timeLog(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.log(d);
+ }
+ }
+
+ public void timeLog10(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.log10(d);
+ }
+ }
+
+ public void timeLog1p(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.log1p(d);
+ }
+ }
+
+ public void timeMaxD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.max(d, d);
+ }
+ }
+
+ public void timeMaxF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.max(f, f);
+ }
+ }
+
+ public void timeMaxI(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.max(i, i);
+ }
+ }
+
+ public void timeMaxL(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.max(l, l);
+ }
+ }
+
+ public void timeMinD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.min(d, d);
+ }
+ }
+
+ public void timeMinF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.min(f, f);
+ }
+ }
+
+ public void timeMinI(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.min(i, i);
+ }
+ }
+
+ public void timeMinL(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.min(l, l);
+ }
+ }
+
+ public void timeNextAfterD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.nextAfter(d, d);
+ }
+ }
+
+ public void timeNextAfterF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.nextAfter(f, f);
+ }
+ }
+
+ public void timeNextUpD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.nextUp(d);
+ }
+ }
+
+ public void timeNextUpF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.nextUp(f);
+ }
+ }
+
+ public void timePow(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.pow(d, d);
+ }
+ }
+
+ public void timeRandom(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.random();
+ }
+ }
+
+ public void timeRint(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.rint(d);
+ }
+ }
+
+ public void timeRoundD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.round(d);
+ }
+ }
+
+ public void timeRoundF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.round(f);
+ }
+ }
+
+ public void timeScalbD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.scalb(d, 5);
+ }
+ }
+
+ public void timeScalbF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.scalb(f, 5);
+ }
+ }
+
+ public void timeSignumD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.signum(d);
+ }
+ }
+
+ public void timeSignumF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.signum(f);
+ }
+ }
+
+ public void timeSin(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.sin(d);
+ }
+ }
+
+ public void timeSinh(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.sinh(d);
+ }
+ }
+
+ public void timeSqrt(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.sqrt(d);
+ }
+ }
+
+ public void timeTan(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.tan(d);
+ }
+ }
+
+ public void timeTanh(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.tanh(d);
+ }
+ }
+
+ public void timeToDegrees(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.toDegrees(d);
+ }
+ }
+
+ public void timeToRadians(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.toRadians(d);
+ }
+ }
+
+ public void timeUlpD(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.ulp(d);
+ }
+ }
+
+ public void timeUlpF(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ StrictMath.ulp(f);
+ }
+ }
+}
diff --git a/benchmarks/regression/StringBenchmark.java b/benchmarks/regression/StringBenchmark.java
new file mode 100644
index 0000000..e09ee8b
--- /dev/null
+++ b/benchmarks/regression/StringBenchmark.java
@@ -0,0 +1,46 @@
+/*
+ * 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.SimpleBenchmark;
+
+public class StringBenchmark extends SimpleBenchmark {
+ enum StringLengths {
+ EMPTY(""),
+ SHORT("short"),
+ EIGHTY(makeString(80)),
+ EIGHT_KI(makeString(8192));
+ final String value;
+ private StringLengths(String value) { this.value = value; }
+ }
+ @Param private StringLengths s;
+
+ private static String makeString(int length) {
+ StringBuilder result = new StringBuilder(length);
+ for (int i = 0; i < length; ++i) {
+ result.append((char) i);
+ }
+ return result.toString();
+ }
+
+ public void timeHashCode(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ s.value.hashCode();
+ }
+ }
+}
diff --git a/benchmarks/regression/StringBuilderBenchmark.java b/benchmarks/regression/StringBuilderBenchmark.java
new file mode 100644
index 0000000..79eff2a
--- /dev/null
+++ b/benchmarks/regression/StringBuilderBenchmark.java
@@ -0,0 +1,132 @@
+/*
+ * 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 the performance of various StringBuilder methods.
+ */
+public class StringBuilderBenchmark extends SimpleBenchmark {
+
+ @Param({"1", "10", "100"}) private int length;
+
+ public void timeAppendBoolean(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(true);
+ }
+ }
+ }
+
+ public void timeAppendChar(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append('c');
+ }
+ }
+ }
+
+ public void timeAppendCharArray(int reps) {
+ char[] chars = "chars".toCharArray();
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(chars);
+ }
+ }
+ }
+
+ public void timeAppendCharSequence(int reps) {
+ CharSequence cs = "chars";
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(cs);
+ }
+ }
+ }
+
+ public void timeAppendDouble(int reps) {
+ double d = 1.2;
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(d);
+ }
+ }
+ }
+
+ public void timeAppendFloat(int reps) {
+ float f = 1.2f;
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(f);
+ }
+ }
+ }
+
+ public void timeAppendInt(int reps) {
+ int n = 123;
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(n);
+ }
+ }
+ }
+
+ public void timeAppendLong(int reps) {
+ long l = 123;
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(l);
+ }
+ }
+ }
+
+ public void timeAppendObject(int reps) {
+ // We don't want to time the toString, so ensure we're calling a trivial one...
+ Object o = new Object() {
+ @Override public String toString() {
+ return "constant";
+ }
+ };
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(o);
+ }
+ }
+ }
+
+ public void timeAppendString(int reps) {
+ String s = "chars";
+ for (int i = 0; i < reps; ++i) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < length; ++j) {
+ sb.append(s);
+ }
+ }
+ }
+}
diff --git a/benchmarks/regression/StringCaseMappingBenchmark.java b/benchmarks/regression/StringCaseMappingBenchmark.java
new file mode 100644
index 0000000..ba5b59e
--- /dev/null
+++ b/benchmarks/regression/StringCaseMappingBenchmark.java
@@ -0,0 +1,150 @@
+/*
+ * 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 java.util.Locale;
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class StringCaseMappingBenchmark extends SimpleBenchmark {
+ enum Inputs {
+ EMPTY(""),
+
+ // TODO: include hairy inputs like turkish and greek.
+ // TODO: locale makes a difference too.
+
+ LOWER2(lower(2)),
+ UPPER2(upper(2)),
+ MIXED2(mixed(2)),
+
+ LOWER8(lower(8)),
+ UPPER8(upper(8)),
+ MIXED8(mixed(8)),
+
+ LOWER32(lower(32)),
+ UPPER32(upper(32)),
+ MIXED32(mixed(32)),
+
+ LOWER512(lower(512)),
+ UPPER512(upper(512)),
+ MIXED512(mixed(512)),
+
+ LOWER2048(lower(2048)),
+ UPPER2048(upper(2048)),
+ MIXED2048(mixed(2048)),
+
+ LOWER_1M(lower(1024*1024)),
+ UPPER_1M(upper(1024*1024)),
+ MIXED_1M(mixed(1024*1024));
+
+ final String value;
+ private Inputs(String value) { this.value = value; }
+ private static String lower(int length) {
+ return makeString(length, "a0b1c2d3e4f5g6h7i8j9klmnopqrstuvwxyz");
+ }
+ private static String upper(int length) {
+ return makeString(length, "A0B1C2D3E4F5G6H7I8J9KLMNOPQRSTUVWXYZ");
+ }
+ private static String mixed(int length) {
+ return makeString(length, "Aa0Bb1Cc2Dd3Ee4Ff5Gg6Hh7Ii8Jj9KkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz");
+ }
+ private static String makeString(int length, String alphabet) {
+ StringBuilder sb = new StringBuilder(length);
+ for (int i = 0; i < length; ++i) {
+ sb.append(alphabet.charAt(i % alphabet.length()));
+ }
+ return sb.toString();
+ }
+ }
+ @Param private Inputs s;
+
+ public void timeToUpperCase_US(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ s.value.toUpperCase(Locale.US);
+ }
+ }
+
+ public void timeToLowerCase_US(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ s.value.toUpperCase(Locale.US);
+ }
+ }
+
+ public void timeToUpperCase_Ascii(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ toUpperCaseAscii(s.value);
+ }
+ }
+
+ public void timeToLowerCase_Ascii(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ toUpperCaseAscii(s.value);
+ }
+ }
+
+ public void timeToUpperCase_ICU(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ libcore.icu.ICU.toUpperCase(s.value, Locale.US.toString());
+ }
+ }
+
+ public void timeToLowerCase_ICU(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ libcore.icu.ICU.toLowerCase(s.value, Locale.US.toString());
+ }
+ }
+
+ public static String toUpperCaseAscii(String s) {
+ for (int i = 0, length = s.length(); i < length; i++) {
+ char c = s.charAt(i);
+ if (c < 'a' || c > 'z') {
+ continue; // fast path avoids allocation
+ }
+
+ // slow path: s contains lower case chars
+ char[] result = s.toCharArray();
+ for (; i < length; i++) {
+ c = result[i];
+ if (c >= 'a' && c <= 'z') {
+ result[i] -= ('a' - 'A');
+ }
+ }
+ return new String(result);
+ }
+ return s;
+ }
+
+ public static String toLowerCaseAscii(String s) {
+ for (int i = 0, length = s.length(); i < length; i++) {
+ char c = s.charAt(i);
+ if (c < 'A' || c > 'Z') {
+ continue; // fast path avoids allocation
+ }
+
+ // slow path: s contains upper case chars
+ char[] result = s.toCharArray();
+ for (; i < length; i++) {
+ c = result[i];
+ if (c >= 'A' && c <= 'Z') {
+ result[i] += ('a' - 'A');
+ }
+ }
+ return new String(result);
+ }
+ return s;
+ }
+}
diff --git a/benchmarks/regression/StringIsEmptyBenchmark.java b/benchmarks/regression/StringIsEmptyBenchmark.java
new file mode 100644
index 0000000..a3be80a
--- /dev/null
+++ b/benchmarks/regression/StringIsEmptyBenchmark.java
@@ -0,0 +1,54 @@
+/*
+ * 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.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+public class StringIsEmptyBenchmark extends SimpleBenchmark {
+ public void timeIsEmpty_NonEmpty(int reps) {
+ boolean result = true;
+ for (int i = 0; i < reps; ++i) {
+ result &= !("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".isEmpty());
+ }
+ if (!result) throw new RuntimeException();
+ }
+
+ public void timeIsEmpty_Empty(int reps) {
+ boolean result = true;
+ for (int i = 0; i < reps; ++i) {
+ result &= ("".isEmpty());
+ }
+ if (!result) throw new RuntimeException();
+ }
+
+ public void timeLengthEqualsZero(int reps) {
+ boolean result = true;
+ for (int i = 0; i < reps; ++i) {
+ result &= !("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length() == 0);
+ }
+ if (!result) throw new RuntimeException();
+ }
+
+ public void timeEqualsEmpty(int reps) {
+ boolean result = true;
+ for (int i = 0; i < reps; ++i) {
+ result &= !"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".equals("");
+ }
+ if (!result) throw new RuntimeException();
+ }
+}
diff --git a/benchmarks/regression/StringLengthBenchmark.java b/benchmarks/regression/StringLengthBenchmark.java
new file mode 100644
index 0000000..962e395
--- /dev/null
+++ b/benchmarks/regression/StringLengthBenchmark.java
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+public class StringLengthBenchmark extends SimpleBenchmark {
+ public void timeLength(int reps) {
+ int length = 0;
+ for (int i = 0; i < reps; ++i) {
+ length = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length();
+ }
+ if (length != 51) throw new RuntimeException();
+ }
+}
diff --git a/benchmarks/regression/StringSplitBenchmark.java b/benchmarks/regression/StringSplitBenchmark.java
new file mode 100644
index 0000000..37fdf8f
--- /dev/null
+++ b/benchmarks/regression/StringSplitBenchmark.java
@@ -0,0 +1,60 @@
+/*
+ * 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.SimpleBenchmark;
+import java.util.regex.Pattern;
+
+public class StringSplitBenchmark extends SimpleBenchmark {
+ public void timeStringSplitComma(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ "this,is,a,simple,example".split(",");
+ }
+ }
+
+ public void timeStringSplitLiteralDot(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ "this.is.a.simple.example".split("\\.");
+ }
+ }
+
+ public void timeStringSplitNewline(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ "this\nis\na\nsimple\nexample\n".split("\n");
+ }
+ }
+
+ public void timePatternSplitComma(int reps) {
+ Pattern p = Pattern.compile(",");
+ for (int i = 0; i < reps; ++i) {
+ p.split("this,is,a,simple,example");
+ }
+ }
+
+ public void timePatternSplitLiteralDot(int reps) {
+ Pattern p = Pattern.compile("\\.");
+ for (int i = 0; i < reps; ++i) {
+ p.split("this.is.a.simple.example");
+ }
+ }
+
+ public void timeStringSplitHard(int reps) {
+ for (int i = 0; i < reps; ++i) {
+ "this,is,a,harder,example".split("[,]");
+ }
+ }
+}
diff --git a/benchmarks/regression/StringToRealBenchmark.java b/benchmarks/regression/StringToRealBenchmark.java
new file mode 100644
index 0000000..ef7a633
--- /dev/null
+++ b/benchmarks/regression/StringToRealBenchmark.java
@@ -0,0 +1,47 @@
+/*
+ * 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.Runner;
+import com.google.caliper.SimpleBenchmark;
+
+public class StringToRealBenchmark extends SimpleBenchmark {
+
+ @Param({
+ "NaN",
+ "-1",
+ "0",
+ "1",
+ "1.2",
+ "-123.45",
+ "-123.45e8",
+ "-123.45e36"
+ }) String string;
+
+ public void timeFloat_parseFloat(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Float.parseFloat(string);
+ }
+ }
+
+ public void timeDouble_parseDouble(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ Double.parseDouble(string);
+ }
+ }
+}
diff --git a/benchmarks/regression/SystemPropertiesBenchmark.java b/benchmarks/regression/SystemPropertiesBenchmark.java
new file mode 100644
index 0000000..9c675e1
--- /dev/null
+++ b/benchmarks/regression/SystemPropertiesBenchmark.java
@@ -0,0 +1,29 @@
+/*
+ * 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.SimpleBenchmark;
+
+public class SystemPropertiesBenchmark extends SimpleBenchmark {
+ public void timeGetProperties(int reps) throws Exception {
+ for (int i = 0; i < reps; ++i) {
+ // Force the properties to be recreated.
+ System.setProperties(null);
+ System.getProperties();
+ }
+ }
+}
diff --git a/benchmarks/regression/ThreadLocalBenchmark.java b/benchmarks/regression/ThreadLocalBenchmark.java
new file mode 100644
index 0000000..df0715b
--- /dev/null
+++ b/benchmarks/regression/ThreadLocalBenchmark.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+public class ThreadLocalBenchmark extends SimpleBenchmark {
+ private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() {
+ @Override protected char[] initialValue() {
+ return new char[20];
+ }
+ };
+
+ public void timeThreadLocal_get(int reps) {
+ for (int rep = 0; rep < reps; ++rep) {
+ BUFFER.get();
+ }
+ }
+}
diff --git a/benchmarks/regression/TimeZoneBenchmark.java b/benchmarks/regression/TimeZoneBenchmark.java
new file mode 100644
index 0000000..ccef392
--- /dev/null
+++ b/benchmarks/regression/TimeZoneBenchmark.java
@@ -0,0 +1,61 @@
+/*
+ * 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.SimpleBenchmark;
+import java.util.TimeZone;
+
+public class TimeZoneBenchmark extends SimpleBenchmark {
+ public void timeTimeZone_getDefault(int reps) throws Exception {
+ for (int rep = 0; rep < reps; ++rep) {
+ TimeZone.getDefault();
+ }
+ }
+
+ public void timeTimeZone_getTimeZoneUTC(int reps) throws Exception {
+ for (int rep = 0; rep < reps; ++rep) {
+ TimeZone.getTimeZone("UTC");
+ }
+ }
+
+ public void timeTimeZone_getTimeZone_default(int reps) throws Exception {
+ String defaultId = TimeZone.getDefault().getID();
+ for (int rep = 0; rep < reps; ++rep) {
+ TimeZone.getTimeZone(defaultId);
+ }
+ }
+
+ // A time zone with relatively few transitions.
+ public void timeTimeZone_getTimeZone_America_Caracas(int reps) throws Exception {
+ for (int rep = 0; rep < reps; ++rep) {
+ TimeZone.getTimeZone("America/Caracas");
+ }
+ }
+
+ // A time zone with a lot of transitions.
+ public void timeTimeZone_getTimeZone_America_Santiago(int reps) throws Exception {
+ for (int rep = 0; rep < reps; ++rep) {
+ TimeZone.getTimeZone("America/Santiago");
+ }
+ }
+
+ public void timeTimeZone_getTimeZone_GMT_plus_10(int reps) throws Exception {
+ for (int rep = 0; rep < reps; ++rep) {
+ TimeZone.getTimeZone("GMT+10");
+ }
+ }
+}
diff --git a/benchmarks/regression/URLConnectionBenchmark.java b/benchmarks/regression/URLConnectionBenchmark.java
new file mode 100644
index 0000000..e5ceec4
--- /dev/null
+++ b/benchmarks/regression/URLConnectionBenchmark.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import tests.http.MockResponse;
+import tests.http.MockWebServer;
+
+public final class URLConnectionBenchmark extends SimpleBenchmark {
+
+ @Param({"0", "1024", "1048576"}) private int bodySize;
+ @Param({"2048"}) private int chunkSize;
+ @Param({"1024"}) private int readBufferSize;
+ @Param private ResponseHeaders responseHeaders;
+ @Param private TransferEncoding transferEncoding;
+ private byte[] readBuffer;
+
+ private MockWebServer server;
+ private URL url;
+
+ protected void setUp() throws Exception {
+ readBuffer = new byte[readBufferSize];
+ server = new MockWebServer();
+
+ MockResponse response = new MockResponse();
+ responseHeaders.apply(response);
+ transferEncoding.setBody(response, bodySize, chunkSize);
+ server.enqueue(response);
+
+ server.setContinuousServing(true);
+ server.play();
+
+ url = server.getUrl("/");
+ get(); // ensure the server has started its threads, etc.
+ }
+
+ protected void tearDown() throws Exception {
+ /*
+ * Entice the server to shut itself down gracefully. The shutdown method
+ * doesn't work on Dalvik because socket.close() doesn't release blocked
+ * threads. Instead, read the last continuously-served request, and then
+ * cause the server to close the otherwise-reusable HTTP connection.
+ */
+ server.setContinuousServing(false);
+ server.enqueue(new MockResponse().setDisconnectAtEnd(true));
+ get();
+ get();
+ server.shutdown();
+ }
+
+ public int timeGet(int reps) throws IOException {
+ int totalBytesRead = 0;
+ for (int i = 0; i < reps; i++) {
+ totalBytesRead += get();
+ }
+ return totalBytesRead;
+ }
+
+ private int get() throws IOException {
+ int totalBytesRead = 0;
+ URLConnection connection = url.openConnection();
+ InputStream in = connection.getInputStream();
+ int count;
+ while ((count = in.read(readBuffer)) != -1) {
+ totalBytesRead += count;
+ }
+ return totalBytesRead;
+ }
+
+ enum TransferEncoding {
+ FIXED_LENGTH,
+ CHUNKED;
+
+ void setBody(MockResponse response, int bodySize, int chunkSize) throws IOException {
+ if (this == TransferEncoding.FIXED_LENGTH) {
+ response.setBody(new byte[bodySize]);
+ } else if (this == TransferEncoding.CHUNKED) {
+ response.setChunkedBody(new byte[bodySize], chunkSize);
+ }
+ }
+ }
+
+ enum ResponseHeaders {
+ MINIMAL,
+ TYPICAL;
+
+ void apply(MockResponse response) {
+ if (this == TYPICAL) {
+ /* from http://api.twitter.com/1/statuses/public_timeline.json */
+ response.addHeader("Date: Wed, 30 Jun 2010 17:57:39 GMT");
+ response.addHeader("Server: hi");
+ response.addHeader("X-RateLimit-Remaining: 0");
+ response.addHeader("X-Runtime: 0.01637");
+ response.addHeader("Content-Type: application/json; charset=utf-8");
+ response.addHeader("X-RateLimit-Class: api_whitelisted");
+ response.addHeader("Cache-Control: no-cache, max-age=300");
+ response.addHeader("X-RateLimit-Reset: 1277920980");
+ response.addHeader("Set-Cookie: _twitter_sess=BAh7EDoOcmV0dXJuX3RvIjZodHRwOi8vZGV2L"
+ + "nR3aXR0ZXIuY29tL3BhZ2Vz%250AL3NpZ25faW5fd2l0aF90d2l0dGVyOgxjc3JmX2lkIiUw"
+ + "ODFhNGY2NTM5NjRm%250ANjY1N2M2NzcwNWI0MDlmZGZjZjoVaW5fbmV3X3VzZXJfZmxvdzA"
+ + "6EXRyYW5z%250AX3Byb21wdDAiKXNob3dfZGlzY292ZXJhYmlsaXR5X2Zvcl9qZXNzZXdpbH"
+ + "Nv%250AbjA6E3Nob3dfaGVscF9saW5rMDoTcGFzc3dvcmRfdG9rZW4iLWUyYjlhNmM3%250A"
+ + "MWJiNzI3NWNlZDI1NDY3MGMzZWNmMTE0MjI4N2EyNGE6D2NyZWF0ZWRfYXRs%250AKwhiM%2"
+ + "52F6JKQE6CXVzZXJpA8tE3iIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxl%250Acjo6Rmxhc2"
+ + "g6OkZsYXNoSGFzaHsABjoKQHVzZWR7ADoHaWQiJWZmMTNhM2Qx%250AZTU1YTkzMmYyMWM0M"
+ + "GNhZjU4NDVjMTQz--11250628c85830219438eb7eba96a541a9af4098; domain=.twitt"
+ + "er.com; path=/");
+ response.addHeader("Expires: Wed, 30 Jun 2010 18:02:39 GMT");
+ response.addHeader("Vary: Accept-Encoding");
+ }
+ }
+ }
+}
diff --git a/benchmarks/regression/XmlEntitiesBenchmark.java b/benchmarks/regression/XmlEntitiesBenchmark.java
new file mode 100644
index 0000000..4c5cc18
--- /dev/null
+++ b/benchmarks/regression/XmlEntitiesBenchmark.java
@@ -0,0 +1,71 @@
+/*
+ * 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.io.StringReader;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.xml.sax.InputSource;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+// http://code.google.com/p/android/issues/detail?id=18102
+public final class XmlEntitiesBenchmark extends SimpleBenchmark {
+
+ @Param({"10", "100", "1000"}) int length;
+ @Param({"0", "0.5", "1.0"}) float entityFraction;
+
+ private XmlPullParserFactory xmlPullParserFactory;
+ private DocumentBuilderFactory documentBuilderFactory;
+
+ /** a string like {@code <doc>&amp;&amp;++</doc>}. */
+ private String xml;
+
+ @Override protected void setUp() throws Exception {
+ xmlPullParserFactory = XmlPullParserFactory.newInstance();
+ documentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+ StringBuilder xmlBuilder = new StringBuilder();
+ xmlBuilder.append("<doc>");
+ for (int i = 0; i < (length * entityFraction); i++) {
+ xmlBuilder.append("&amp;");
+ }
+ while (xmlBuilder.length() < length) {
+ xmlBuilder.append("+");
+ }
+ xmlBuilder.append("</doc>");
+ xml = xmlBuilder.toString();
+ }
+
+ public void timeXmlParser(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ XmlPullParser parser = xmlPullParserFactory.newPullParser();
+ parser.setInput(new StringReader(xml));
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ }
+ }
+ }
+
+ public void timeDocumentBuilder(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ documentBuilder.parse(new InputSource(new StringReader(xml)));
+ }
+ }
+}