Merge "Additional libcore benchmarks." am: e81851f57b

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2067207

Change-Id: I0a6631b033d46f407a93e3427ecfb7eadfd8246e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Miguel Aranda
2022-04-21 13:32:56 +00:00
committed by Automerger Merge Worker
21 changed files with 5107 additions and 0 deletions

View File

@@ -0,0 +1,220 @@
/*
* Copyright (C) 2020 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.math.BigInteger;
/**
* Tries to measure important BigInteger operations across a variety of BigInteger sizes. Note that
* BigInteger implementations commonly need to use wildly different algorithms for different sizes,
* so relative performance may change substantially depending on the size of the integer. This is
* not structured as a proper benchmark; just run main(), e.g. with vogar
* libcore/benchmarks/src/benchmarks/BigIntegerBenchmark.java.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class BigIntegerPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
// A simple sum of products computation, mostly so we can check timing in the
// absence of any division. Computes the sum from 1 to n of ((10^prec) << 30) + 1)^2,
// repeating the multiplication, but not addition of 1, each time through the loop.
// Check the last few bits of the result as we go. Assumes n < 2^30.
// Note that we're actually squaring values in computing the product.
// That affects the algorithm used by some implementations.
private static void inner(int n, int prec) {
BigInteger big = BigInteger.TEN.pow(prec).shiftLeft(30).add(BigInteger.ONE);
BigInteger sum = BigInteger.ZERO;
for (int i = 0; i < n; ++i) {
sum = sum.add(big.multiply(big));
}
if (sum.and(BigInteger.valueOf(0x3fffffff)).intValue() != n) {
throw new AssertionError(
"inner() got " + sum.and(BigInteger.valueOf(0x3fffffff)) + " instead of " + n);
}
}
// Execute the above rep times, optionally timing it.
@Test
public void repeatInner() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
for (int i = 10; i <= 10_000; i *= 10) {
inner(100, i);
}
}
}
// Approximate the sum of the first 1000 terms of the harmonic series (sum of 1/m as m
// goes from 1 to n) to about prec digits. The result has an implicit decimal point
// prec digits from the right.
private static BigInteger harmonic1000(int prec) {
BigInteger scaledOne = BigInteger.TEN.pow(prec);
BigInteger sum = BigInteger.ZERO;
for (int i = 1; i <= 1000; ++i) {
sum = sum.add(scaledOne.divide(BigInteger.valueOf(i)));
}
return sum;
}
// Execute the above rep times, optionally timing it.
// Check results for equality, and print one, to compaare against reference.
@Test
public void repeatHarmonic1000() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
for (int i = 5; i <= 5_000; i *= 10) {
BigInteger refRes = harmonic1000(i);
BigInteger newRes = harmonic1000(i);
if (!newRes.equals(refRes)) {
throw new AssertionError(newRes + " != " + refRes);
}
if (i >= 50
&& !refRes.toString()
.startsWith("748547086055034491265651820433390017652167916970")) {
throw new AssertionError("harmanic(" + i + ") incorrectly produced " + refRes);
}
}
}
}
// Repeatedly execute just the base conversion from the last test, allowing
// us to time and check it for consistency as well.
@Test
public void repeatToString() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
for (int i = 5; i <= 5_000; i *= 10) {
BigInteger refRes = harmonic1000(i);
String refString = refRes.toString();
// Disguise refRes to avoid compiler optimization issues.
BigInteger newRes = refRes.shiftLeft(30).add(BigInteger.valueOf(i)).shiftRight(30);
// The time-consuming part:
String newString = newRes.toString();
}
}
}
// Compute base^exp, where base and result are scaled/multiplied by scaleBy to make them
// integers. exp >= 0 .
private static BigInteger myPow(BigInteger base, int exp, BigInteger scaleBy) {
if (exp == 0) {
return scaleBy; // Return one.
} else if ((exp & 1) != 0) {
BigInteger tmp = myPow(base, exp - 1, scaleBy);
return tmp.multiply(base).divide(scaleBy);
} else {
BigInteger tmp = myPow(base, exp / 2, scaleBy);
return tmp.multiply(tmp).divide(scaleBy);
}
}
// Approximate e by computing (1 + 1/n)^n to prec decimal digits.
// This isn't necessarily a very good approximation to e.
// Return the result, scaled by 10^prec.
private static BigInteger eApprox(int n, int prec) {
BigInteger scaledOne = BigInteger.TEN.pow(prec);
BigInteger base = scaledOne.add(scaledOne.divide(BigInteger.valueOf(n)));
return myPow(base, n, scaledOne);
}
// Repeatedly execute and check the above, printing one of the results
// to compare to reference.
@Test
public void repeatEApprox() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
for (int i = 10; i <= 10_000; i *= 10) {
BigInteger refRes = eApprox(100_000, i);
BigInteger newRes = eApprox(100_000, i);
if (!newRes.equals(refRes)) {
throw new AssertionError(newRes + " != " + refRes);
}
if (i >= 10 && !refRes.toString().startsWith("271826")) {
throw new AssertionError(
"eApprox(" + 100_000 + "," + i + ") incorrectly produced " + refRes);
}
}
}
}
// Test / time modPow()
@Test
public void repeatModPow() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
for (int i = 5; i <= 500; i *= 10) {
BigInteger odd1 = BigInteger.TEN.pow(i / 2).add(BigInteger.ONE);
BigInteger odd2 = BigInteger.TEN.pow(i / 2).add(BigInteger.valueOf(17));
BigInteger product = odd1.multiply(odd2);
BigInteger exponent = BigInteger.TEN.pow(i / 2 - 1);
BigInteger base = BigInteger.TEN.pow(i / 4);
BigInteger newRes = base.modPow(exponent, product);
if (!newRes.mod(odd1).equals(base.modPow(exponent, odd1))) {
throw new AssertionError(
"ModPow() result incorrect mod odd1:"
+ odd1
+ "; lastRes.mod(odd1)="
+ newRes.mod(odd1)
+ " vs. "
+ "base.modPow(exponent, odd1)="
+ base.modPow(exponent, odd1)
+ " base="
+ base
+ " exponent="
+ exponent);
}
if (!newRes.mod(odd2).equals(base.modPow(exponent, odd2))) {
throw new AssertionError("ModPow() result incorrect mod odd2");
}
}
}
}
// Test / time modInverse()
@Test
public void repeatModInverse() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
for (int i = 10; i <= 10_000; i *= 10) {
BigInteger odd1 = BigInteger.TEN.pow(i / 2).add(BigInteger.ONE);
BigInteger odd2 = BigInteger.TEN.pow(i / 2).add(BigInteger.valueOf(17));
BigInteger product = odd1.multiply(odd2);
BigInteger arg = BigInteger.ONE.shiftLeft(i / 4);
BigInteger lastRes = null;
BigInteger newRes = arg.modInverse(product);
lastRes = newRes;
if (!lastRes.mod(odd1).equals(arg.modInverse(odd1))) {
throw new AssertionError("ModInverse() result incorrect mod odd1");
}
if (!lastRes.mod(odd2).equals(arg.modInverse(odd2))) {
throw new AssertionError("ModInverse() result incorrect mod odd2");
}
}
}
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
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;
@RunWith(AndroidJUnit4.class)
@LargeTest
public final class BufferedZipFilePerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
int[] mReadSize = new int[] {4, 32, 128};
int[] mCompressedSize = new int[] {128, 1024, 8192, 65536};
private File mFile;
@Before
public void setUp() throws Exception {
mFile = File.createTempFile("BufferedZipFilePerfTest", ".zip");
mFile.deleteOnExit();
Random random = new Random(0);
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(mFile));
for (int i = 0; i < mCompressedSize.length; i++) {
byte[] data = new byte[8192];
out.putNextEntry(new ZipEntry("entry.data" + mCompressedSize[i]));
int written = 0;
while (written < mCompressedSize[i]) {
random.nextBytes(data);
int toWrite = Math.min(mCompressedSize[i] - written, data.length);
out.write(data, 0, toWrite);
written += toWrite;
}
}
out.close();
}
@Test
public void timeUnbufferedRead() throws Exception {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
for (int i = 0; i < mCompressedSize.length; i++) {
for (int j = 0; j < mReadSize.length; j++) {
ZipFile zipFile = new ZipFile(mFile);
ZipEntry entry = zipFile.getEntry("entry.data" + mCompressedSize[i]);
InputStream in = zipFile.getInputStream(entry);
byte[] buffer = new byte[mReadSize[j]];
while (in.read(buffer) != -1) {
// Keep reading
}
in.close();
zipFile.close();
}
}
}
}
@Test
public void timeBufferedRead() throws Exception {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
for (int i = 0; i < mCompressedSize.length; i++) {
for (int j = 0; j < mReadSize.length; j++) {
ZipFile zipFile = new ZipFile(mFile);
ZipEntry entry = zipFile.getEntry("entry.data" + mCompressedSize[i]);
InputStream in = new BufferedInputStream(zipFile.getInputStream(entry));
byte[] buffer = new byte[mReadSize[j]];
while (in.read(buffer) != -1) {
// Keep reading
}
in.close();
zipFile.close();
}
}
}
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ClassLoaderResourcePerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
private static final String EXISTENT_RESOURCE = "java/util/logging/logging.properties";
private static final String MISSING_RESOURCE = "missing_entry";
@Test
public void timeGetBootResource_hit() {
ClassLoader currentClassLoader = getClass().getClassLoader();
Assert.assertNotNull(currentClassLoader.getResource(EXISTENT_RESOURCE));
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
currentClassLoader.getResource(EXISTENT_RESOURCE);
}
}
@Test
public void timeGetBootResource_miss() {
ClassLoader currentClassLoader = getClass().getClassLoader();
Assert.assertNull(currentClassLoader.getResource(MISSING_RESOURCE));
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
currentClassLoader.getResource(MISSING_RESOURCE);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,169 @@
/*
* Copyright (C) 2013 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
@LargeTest
public class DeepArrayOpsPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
private Object[] mArray;
private Object[] mArray2;
@Parameterized.Parameter(0)
public int mArrayLength;
@Parameterized.Parameters(name = "mArrayLength({0})")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {{1}, {4}, {16}, {32}, {2048}});
}
@Before
public void setUp() throws Exception {
mArray = new Object[mArrayLength * 14];
mArray2 = new Object[mArrayLength * 14];
for (int i = 0; i < mArrayLength; i += 14) {
mArray[i] = new IntWrapper(i);
mArray2[i] = new IntWrapper(i);
mArray[i + 1] = new16ElementObjectmArray();
mArray2[i + 1] = new16ElementObjectmArray();
mArray[i + 2] = new boolean[16];
mArray2[i + 2] = new boolean[16];
mArray[i + 3] = new byte[16];
mArray2[i + 3] = new byte[16];
mArray[i + 4] = new char[16];
mArray2[i + 4] = new char[16];
mArray[i + 5] = new short[16];
mArray2[i + 5] = new short[16];
mArray[i + 6] = new float[16];
mArray2[i + 6] = new float[16];
mArray[i + 7] = new long[16];
mArray2[i + 7] = new long[16];
mArray[i + 8] = new int[16];
mArray2[i + 8] = new int[16];
mArray[i + 9] = new double[16];
mArray2[i + 9] = new double[16];
// SubmArray types are concrete objects.
mArray[i + 10] = new16ElementArray(String.class, String.class);
mArray2[i + 10] = new16ElementArray(String.class, String.class);
mArray[i + 11] = new16ElementArray(Integer.class, Integer.class);
mArray2[i + 11] = new16ElementArray(Integer.class, Integer.class);
// SubmArray types is an interface.
mArray[i + 12] = new16ElementArray(CharSequence.class, String.class);
mArray2[i + 12] = new16ElementArray(CharSequence.class, String.class);
mArray[i + 13] = null;
mArray2[i + 13] = null;
}
}
@Test
public void deepHashCode() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
Arrays.deepHashCode(mArray);
}
}
@Test
public void deepEquals() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
Arrays.deepEquals(mArray, mArray2);
}
}
private static Object[] new16ElementObjectmArray() {
Object[] array = new Object[16];
for (int i = 0; i < 16; ++i) {
array[i] = new IntWrapper(i);
}
return array;
}
@SuppressWarnings("unchecked")
private static <T, V> T[] new16ElementArray(Class<T> mArrayType, Class<V> type)
throws Exception {
T[] array = (T[]) Array.newInstance(type, 16);
if (!mArrayType.isAssignableFrom(type)) {
throw new IllegalArgumentException(mArrayType + " is not assignable from " + type);
}
Constructor<V> constructor = type.getDeclaredConstructor(String.class);
for (int i = 0; i < 16; ++i) {
array[i] = (T) constructor.newInstance(String.valueOf(i + 1000));
}
return array;
}
/**
* A class that provides very basic equals() and hashCode() operations and doesn't resort to
* memoization tricks like {@link java.lang.Integer}.
*
* <p>Useful for providing equal objects that aren't the same (a.equals(b) but a != b).
*/
public static final class IntWrapper {
private final int mWrapped;
public IntWrapper(int wrap) {
mWrapped = wrap;
}
@Override
public int hashCode() {
return mWrapped;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof IntWrapper)) {
return false;
}
return ((IntWrapper) o).mWrapped == this.mWrapped;
}
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/** What does field access cost? */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class FieldAccessPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
private static class Inner {
public int mPublicInnerIntVal;
protected int mProtectedInnerIntVal;
private int mPrivateInnerIntVal;
int mPackageInnerIntVal;
}
int mIntVal = 42;
final int mFinalIntVal = 42;
static int sStaticIntVal = 42;
static final int FINAL_INT_VAL = 42;
@Test
public void timeField() {
int result = 0;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = mIntVal;
}
}
@Test
public void timeFieldFinal() {
int result = 0;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = mFinalIntVal;
}
}
@Test
public void timeFieldStatic() {
int result = 0;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = sStaticIntVal;
}
}
@Test
public void timeFieldStaticFinal() {
int result = 0;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = FINAL_INT_VAL;
}
}
@Test
public void timeFieldCached() {
int result = 0;
int cachedIntVal = this.mIntVal;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = cachedIntVal;
}
}
@Test
public void timeFieldPrivateInnerClassPublicField() {
int result = 0;
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = inner.mPublicInnerIntVal;
}
}
@Test
public void timeFieldPrivateInnerClassProtectedField() {
int result = 0;
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = inner.mProtectedInnerIntVal;
}
}
@Test
public void timeFieldPrivateInnerClassPrivateField() {
int result = 0;
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = inner.mPrivateInnerIntVal;
}
}
@Test
public void timeFieldPrivateInnerClassPackageField() {
int result = 0;
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = inner.mPackageInnerIntVal;
}
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap;
/** How do the various hash maps compare? */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class HashedCollectionsPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Test
public void timeHashMapGet() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("hello", "world");
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
map.get("hello");
}
}
@Test
public void timeHashMapGet_Synchronized() {
HashMap<String, String> map = new HashMap<String, String>();
synchronized (map) {
map.put("hello", "world");
}
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
synchronized (map) {
map.get("hello");
}
}
}
@Test
public void timeHashtableGet() {
Hashtable<String, String> map = new Hashtable<String, String>();
map.put("hello", "world");
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
map.get("hello");
}
}
@Test
public void timeLinkedHashMapGet() {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("hello", "world");
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
map.get("hello");
}
}
@Test
public void timeConcurrentHashMapGet() {
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>();
map.put("hello", "world");
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
map.get("hello");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,121 @@
#!/usr/bin/env python3
#
# Copyright 2016 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.
#
import sys
max_conflict_depth = 20 # In practice does not go above 20 for reasonable IMT sizes
try:
imt_size = int(sys.argv[1])
except (IndexError, ValueError):
print("Usage: python ImtConflictPerfTestGen.py <IMT_SIZE>")
sys.exit(1)
license = """\
/*
* Copyright 2016 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.
*/
"""
description = """
/**
* This file is script-generated by ImtConflictPerfTestGen.py.
* It measures the performance impact of conflicts in interface method tables.
* Run `python ImtConflictPerfTestGen.py > ImtConflictPerfTest.java` to regenerate.
*
* Each interface has 64 methods, which is the current size of an IMT. C0 implements
* one interface, C1 implements two, C2 implements three, and so on. The intent
* is that C0 has no conflicts in its IMT, C1 has depth-2 conflicts in
* its IMT, C2 has depth-3 conflicts, etc. This is currently guaranteed by
* the fact that we hash interface methods by taking their method index modulo 64.
* (Note that a "conflict depth" of 1 means no conflict at all.)
*/\
"""
print(license)
print("package android.libcore;")
imports = """
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
"""
print(imports)
print(description)
print("@RunWith(AndroidJUnit4.class)")
print("@LargeTest")
print("public class ImtConflictPerfTest {")
print(" @Rule")
print(" public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();")
print("")
# Warm up interface method tables
print(" @Before")
print(" public void setup() {")
for i in range(max_conflict_depth):
print(" C{0} c{0} = new C{0}();".format(i))
for j in range(i+1):
print(" callF{}(c{});".format(imt_size * j, i))
print(" }")
# Print test cases--one for each conflict depth
for i in range(max_conflict_depth):
print(" @Test")
print(" public void timeConflictDepth{:02d}() {{".format(i+1))
print(" C{0} c{0} = new C{0}();".format(i))
print(" BenchmarkState state = mPerfStatusReporter.getBenchmarkState();")
print(" while (state.keepRunning()) {")
# Cycle through each interface method in an IMT entry in order
# to test all conflict resolution possibilities
for j in range(max_conflict_depth):
print(" callF{}(c{});".format(imt_size * (j % (i + 1)), i))
print(" }")
print(" }")
# Make calls through the IMTs
for i in range(max_conflict_depth):
print(" public void callF{0}(I{1} i) {{ i.f{0}(); }}".format(imt_size*i, i))
# Class definitions, implementing varying amounts of interfaces
for i in range(max_conflict_depth):
interfaces = ", ".join(["I{}".format(j) for j in range(i+1)])
print(" static class C{} implements {} {{}}".format(i, interfaces))
# Interface definitions, each with enough methods to fill an entire IMT
for i in range(max_conflict_depth):
print(" interface I{} {{".format(i))
for j in range(imt_size):
print(" default void f{}() {{}}".format(i*imt_size + j))
print(" }")
print("}")

View File

@@ -0,0 +1,182 @@
/*
* Copyright 2016 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Compares various kinds of method invocation. */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MethodInvocationPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
interface I {
void emptyInterface();
}
static class C implements I {
private int mField;
private int getField() {
return mField;
}
public void timeInternalGetter(BenchmarkState state) {
int result = 0;
while (state.keepRunning()) {
result = getField();
}
}
public void timeInternalFieldAccess(BenchmarkState state) {
int result = 0;
while (state.keepRunning()) {
result = mField;
}
}
public static void emptyStatic() {}
public void emptyVirtual() {}
public void emptyInterface() {}
}
public void timeInternalGetter() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
new C().timeInternalGetter(state);
}
public void timeInternalFieldAccess() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
new C().timeInternalFieldAccess(state);
}
// Test an intrinsic.
@Test
public void timeStringLength() {
int result = 0;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result = "hello, world!".length();
}
}
@Test
public void timeEmptyStatic() {
C c = new C();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
c.emptyStatic();
}
}
@Test
public void timeEmptyVirtual() {
C c = new C();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
c.emptyVirtual();
}
}
@Test
public void timeEmptyInterface() {
I c = new C();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
c.emptyInterface();
}
}
public static class Inner {
private int mI;
private void privateMethod() {
++mI;
}
protected void protectedMethod() {
++mI;
}
public void publicMethod() {
++mI;
}
void packageMethod() {
++mI;
}
final void finalPackageMethod() {
++mI;
}
}
@Test
public void timePrivateInnerPublicMethod() {
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
inner.publicMethod();
}
}
@Test
public void timePrivateInnerProtectedMethod() {
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
inner.protectedMethod();
}
}
@Test
public void timePrivateInnerPrivateMethod() {
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
inner.privateMethod();
}
}
@Test
public void timePrivateInnerPackageMethod() {
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
inner.packageMethod();
}
}
@Test
public void timePrivateInnerFinalPackageMethod() {
Inner inner = new Inner();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
inner.finalPackageMethod();
}
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/** How much do various kinds of multiplication cost? */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MultiplicationPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Test
public void timeMultiplyIntByConstant10() {
int result = 1;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result *= 10;
}
}
@Test
public void timeMultiplyIntByConstant8() {
int result = 1;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result *= 8;
}
}
@Test
public void timeMultiplyIntByVariable10() {
int result = 1;
int factor = 10;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result *= factor;
}
}
@Test
public void timeMultiplyIntByVariable8() {
int result = 1;
int factor = 8;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
result *= factor;
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2014 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ReferenceGetPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
boolean mIntrinsicDisabled;
private Object mObj = "str";
@Before
public void setUp() throws Exception {
Field intrinsicDisabledField = Reference.class.getDeclaredField("disableIntrinsic");
intrinsicDisabledField.setAccessible(true);
intrinsicDisabledField.setBoolean(null, mIntrinsicDisabled);
}
@Test
public void timeSoftReferenceGet() throws Exception {
Reference soft = new SoftReference(mObj);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
Object o = soft.get();
}
}
@Test
public void timeWeakReferenceGet() throws Exception {
Reference weak = new WeakReference(mObj);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
Object o = weak.get();
}
}
@Test
public void timeNonPreservedWeakReferenceGet() throws Exception {
Reference weak = new WeakReference(mObj);
mObj = null;
Runtime.getRuntime().gc();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
Object o = weak.get();
}
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2015 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.concurrent.atomic.AtomicInteger;
/** Benchmark to evaluate the performance of References. */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ReferencePerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
private Object mObject;
// How fast can references can be allocated?
@Test
public void timeAlloc() {
ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
new PhantomReference(mObject, queue);
}
}
// How fast can references can be allocated and manually enqueued?
@Test
public void timeAllocAndEnqueue() {
ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
(new PhantomReference<Object>(mObject, queue)).enqueue();
}
}
// How fast can references can be allocated, enqueued, and polled?
@Test
public void timeAllocEnqueueAndPoll() {
ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
(new PhantomReference<Object>(mObject, queue)).enqueue();
queue.poll();
}
}
// How fast can references can be allocated, enqueued, and removed?
@Test
public void timeAllocEnqueueAndRemove() {
ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
(new PhantomReference<Object>(mObject, queue)).enqueue();
try {
queue.remove();
} catch (InterruptedException ie) {
}
}
}
private static class FinalizableObject {
AtomicInteger mCount;
FinalizableObject(AtomicInteger count) {
this.mCount = count;
}
@Override
protected void finalize() {
mCount.incrementAndGet();
}
}
// How fast does finalization run?
@Test
public void timeFinalization() {
// Allocate a bunch of finalizable objects.
int n = 0;
AtomicInteger count = new AtomicInteger(0);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
n++;
new FinalizableObject(count);
}
// Run GC so the objects will be collected for finalization.
Runtime.getRuntime().gc();
// Wait for finalization.
Runtime.getRuntime().runFinalization();
// Double check all the objects were finalized.
int got = count.get();
if (n != got) {
throw new IllegalStateException(
String.format("Only %i of %i objects finalized?", got, n));
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.math.BigInteger;
import java.util.Random;
/**
* This measures performance of operations on small BigIntegers. We manually determine the number of
* iterations so that it should cause total memory allocation on the order of a few hundred
* megabytes. Due to BigInteger's reliance on finalization, these may unfortunately all be kept
* around at once.
*
* <p>This is not structured as a proper benchmark; just run main(), e.g. with vogar
* libcore/benchmarks/src/benchmarks/SmallBigIntegerBenchmark.java
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class SmallBigIntegerPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
// We allocate about 2 1/3 BigIntegers per iteration.
// Assuming 100 bytes/BigInteger, this gives us around 500MB total.
static final BigInteger BIG_THREE = BigInteger.valueOf(3);
static final BigInteger BIG_FOUR = BigInteger.valueOf(4);
@Test
public void testSmallBigInteger() {
final Random r = new Random();
BigInteger x = new BigInteger(20, r);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
// We know this converges, but the compiler doesn't.
if (x.and(BigInteger.ONE).equals(BigInteger.ONE)) {
x = x.multiply(BIG_THREE).add(BigInteger.ONE);
} else {
x = x.shiftRight(1);
}
}
if (x.signum() < 0 || x.compareTo(BIG_FOUR) > 0) {
throw new AssertionError("Something went horribly wrong.");
}
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/** How long does it take to access a string in the dex cache? */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class StringDexCachePerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Test
public void timeStringDexCacheAccess() {
int v = 0;
int count = 0;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
// Deliberately obscured to make optimizations less likely.
String s = (count >= 0) ? "hello, world!" : null;
v += s.length();
++count;
}
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/** How do the various schemes for iterating through a string compare? */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class StringIterationPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Test
public void timeStringIteration0() {
String s = "hello, world!";
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
char ch;
for (int i = 0; i < s.length(); ++i) {
ch = s.charAt(i);
}
}
}
@Test
public void timeStringIteration1() {
String s = "hello, world!";
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
char ch;
for (int i = 0, length = s.length(); i < length; ++i) {
ch = s.charAt(i);
}
}
}
@Test
public void timeStringIteration2() {
String s = "hello, world!";
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
char ch;
char[] chars = s.toCharArray();
for (int i = 0, length = chars.length; i < length; ++i) {
ch = chars[i];
}
}
}
@Test
public void timeStringToCharArray() {
String s = "hello, world!";
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
char[] chars = s.toCharArray();
}
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
@LargeTest
public class SystemArrayCopyPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Parameters(name = "arrayLength={0}")
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[][] {
{2}, {4}, {8}, {16}, {32}, {64}, {128}, {256}, {512}, {1024}, {2048}, {4096},
{8192}, {16384}, {32768}, {65536}, {131072}, {262144}
});
}
@Parameterized.Parameter(0)
public int arrayLength;
// Provides benchmarking for different types of arrays using the arraycopy function.
@Test
public void timeSystemCharArrayCopy() {
final int len = arrayLength;
char[] src = new char[len];
char[] dst = new char[len];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
System.arraycopy(src, 0, dst, 0, len);
}
}
@Test
public void timeSystemByteArrayCopy() {
final int len = arrayLength;
byte[] src = new byte[len];
byte[] dst = new byte[len];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
System.arraycopy(src, 0, dst, 0, len);
}
}
@Test
public void timeSystemShortArrayCopy() {
final int len = arrayLength;
short[] src = new short[len];
short[] dst = new short[len];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
System.arraycopy(src, 0, dst, 0, len);
}
}
@Test
public void timeSystemIntArrayCopy() {
final int len = arrayLength;
int[] src = new int[len];
int[] dst = new int[len];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
System.arraycopy(src, 0, dst, 0, len);
}
}
@Test
public void timeSystemLongArrayCopy() {
final int len = arrayLength;
long[] src = new long[len];
long[] dst = new long[len];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
System.arraycopy(src, 0, dst, 0, len);
}
}
@Test
public void timeSystemFloatArrayCopy() {
final int len = arrayLength;
float[] src = new float[len];
float[] dst = new float[len];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
System.arraycopy(src, 0, dst, 0, len);
}
}
@Test
public void timeSystemDoubleArrayCopy() {
final int len = arrayLength;
double[] src = new double[len];
double[] dst = new double[len];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
System.arraycopy(src, 0, dst, 0, len);
}
}
@Test
public void timeSystemBooleanArrayCopy() {
final int len = arrayLength;
boolean[] src = new boolean[len];
boolean[] dst = new boolean[len];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
System.arraycopy(src, 0, dst, 0, len);
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.HashMap;
import java.util.Map;
/**
* Is there a performance reason to "Prefer virtual over interface", as the Android documentation
* once claimed?
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class VirtualVersusInterfacePerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Test
public void timeMapPut() {
Map<String, String> map = new HashMap<String, String>();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
map.put("hello", "world");
}
}
@Test
public void timeHashMapPut() {
HashMap<String, String> map = new HashMap<String, String>();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
map.put("hello", "world");
}
}
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright (C) 2022 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.xmlpull.v1.XmlSerializer;
import java.io.CharArrayWriter;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collection;
import java.util.Random;
@RunWith(Parameterized.class)
@LargeTest
public class XmlSerializePerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Parameters(name = "mDatasetAsString({0}), mSeed({1})")
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[][] {
{"0.99 0.7 0.7 0.7 0.7 0.7", 854328},
{"0.999 0.3 0.3 0.95 0.9 0.9", 854328},
{"0.99 0.7 0.7 0.7 0.7 0.7", 312547},
{"0.999 0.3 0.3 0.95 0.9 0.9", 312547}
});
}
@Parameterized.Parameter(0)
public String mDatasetAsString;
@Parameterized.Parameter(1)
public int mSeed;
double[] mDataset;
private Constructor<? extends XmlSerializer> mKxmlConstructor;
private Constructor<? extends XmlSerializer> mFastConstructor;
private void serializeRandomXml(Constructor<? extends XmlSerializer> ctor, long mSeed)
throws Exception {
double contChance = mDataset[0];
double levelUpChance = mDataset[1];
double levelDownChance = mDataset[2];
double attributeChance = mDataset[3];
double writeChance1 = mDataset[4];
double writeChance2 = mDataset[5];
XmlSerializer serializer = (XmlSerializer) ctor.newInstance();
CharArrayWriter w = new CharArrayWriter();
serializer.setOutput(w);
int level = 0;
Random r = new Random(mSeed);
char[] toWrite = {'a', 'b', 'c', 'd', 's', 'z'};
serializer.startDocument("UTF-8", true);
while (r.nextDouble() < contChance) {
while (level > 0 && r.nextDouble() < levelUpChance) {
serializer.endTag("aaaaaa", "bbbbbb");
level--;
}
while (r.nextDouble() < levelDownChance) {
serializer.startTag("aaaaaa", "bbbbbb");
level++;
}
serializer.startTag("aaaaaa", "bbbbbb");
level++;
while (r.nextDouble() < attributeChance) {
serializer.attribute("aaaaaa", "cccccc", "dddddd");
}
serializer.endTag("aaaaaa", "bbbbbb");
level--;
while (r.nextDouble() < writeChance1) serializer.text(toWrite, 0, 5);
while (r.nextDouble() < writeChance2) serializer.text("Textxtsxtxtxt ");
}
serializer.endDocument();
}
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
mKxmlConstructor =
(Constructor)
Class.forName("com.android.org.kxml2.io.KXmlSerializer").getConstructor();
mFastConstructor =
(Constructor)
Class.forName("com.android.internal.util.FastXmlSerializer")
.getConstructor();
String[] splitStrings = mDatasetAsString.split(" ");
mDataset = new double[splitStrings.length];
for (int i = 0; i < splitStrings.length; i++) {
mDataset[i] = Double.parseDouble(splitStrings[i]);
}
}
private void internalTimeSerializer(Constructor<? extends XmlSerializer> ctor)
throws Exception {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
serializeRandomXml(ctor, mSeed);
}
}
@Test
public void timeKxml() throws Exception {
internalTimeSerializer(mKxmlConstructor);
}
@Test
public void timeFast() throws Exception {
internalTimeSerializer(mFastConstructor);
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2016 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
@RunWith(Parameterized.class)
@LargeTest
public class ZipFilePerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
private File mFile;
@Parameters(name = "numEntries={0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {{128}, {1024}, {8192}});
}
@Parameterized.Parameter(0)
public int numEntries;
@Before
public void setUp() throws Exception {
mFile = File.createTempFile(getClass().getName(), ".zip");
mFile.deleteOnExit();
writeEntries(new ZipOutputStream(new FileOutputStream(mFile)), numEntries, 0);
ZipFile zipFile = new ZipFile(mFile);
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
ZipEntry zipEntry = e.nextElement();
}
zipFile.close();
}
@Test
public void timeZipFileOpen() throws Exception {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
ZipFile zf = new ZipFile(mFile);
}
}
/** Compresses the given number of files, each of the given size, into a .zip archive. */
protected void writeEntries(ZipOutputStream out, int entryCount, long entrySize)
throws IOException {
byte[] writeBuffer = new byte[8192];
Random random = new Random();
try {
for (int entry = 0; entry < entryCount; ++entry) {
ZipEntry ze = new ZipEntry(Integer.toHexString(entry));
ze.setSize(entrySize);
out.putNextEntry(ze);
for (long i = 0; i < entrySize; i += writeBuffer.length) {
random.nextBytes(writeBuffer);
int byteCount = (int) Math.min(writeBuffer.length, entrySize - i);
out.write(writeBuffer, 0, byteCount);
}
out.closeEntry();
}
} finally {
out.close();
}
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2017 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 android.libcore;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.test.suitebuilder.annotation.LargeTest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
@RunWith(Parameterized.class)
@LargeTest
public class ZipFileReadPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Parameters(name = "readBufferSize={0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {{1024}, {16384}, {65536}});
}
private File mFile;
@Parameterized.Parameter(0)
public int readBufferSize;
@Before
public void setUp() throws Exception {
mFile = File.createTempFile(getClass().getName(), ".zip");
writeEntries(new ZipOutputStream(new FileOutputStream(mFile)), 2, 1024 * 1024);
ZipFile zipFile = new ZipFile(mFile);
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
ZipEntry zipEntry = e.nextElement();
}
zipFile.close();
}
/** Compresses the given number of files, each of the given size, into a .zip archive. */
protected void writeEntries(ZipOutputStream out, int entryCount, long entrySize)
throws IOException {
byte[] writeBuffer = new byte[8192];
Random random = new Random();
try {
for (int entry = 0; entry < entryCount; ++entry) {
ZipEntry ze = new ZipEntry(Integer.toHexString(entry));
ze.setSize(entrySize);
out.putNextEntry(ze);
for (long i = 0; i < entrySize; i += writeBuffer.length) {
random.nextBytes(writeBuffer);
int byteCount = (int) Math.min(writeBuffer.length, entrySize - i);
out.write(writeBuffer, 0, byteCount);
}
out.closeEntry();
}
} finally {
out.close();
}
}
@Test
public void timeZipFileRead() throws Exception {
byte[] readBuffer = new byte[readBufferSize];
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
ZipFile zipFile = new ZipFile(mFile);
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
ZipEntry zipEntry = e.nextElement();
InputStream is = zipFile.getInputStream(zipEntry);
while (true) {
if (is.read(readBuffer, 0, readBuffer.length) < 0) {
break;
}
}
}
zipFile.close();
}
}
}