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:
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1197
apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java
Normal file
1197
apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
121
apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTestGen.py
Executable file
121
apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTestGen.py
Executable 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("}")
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user