1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.libcore.regression; 18 19 import android.perftests.utils.BenchmarkState; 20 import android.perftests.utils.PerfStatusReporter; 21 22 import androidx.test.filters.LargeTest; 23 24 import junitparams.JUnitParamsRunner; 25 import junitparams.Parameters; 26 27 import org.junit.Rule; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 31 import java.nio.ByteBuffer; 32 import java.security.MessageDigest; 33 import java.util.Arrays; 34 import java.util.Collection; 35 36 @RunWith(JUnitParamsRunner.class) 37 @LargeTest 38 public class MessageDigestPerfTest { 39 @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); 40 getData()41 public static Collection<Object[]> getData() { 42 return Arrays.asList( 43 new Object[][] { 44 {Algorithm.MD5}, 45 {Algorithm.SHA1}, 46 {Algorithm.SHA256}, 47 {Algorithm.SHA384}, 48 {Algorithm.SHA512} 49 }); 50 } 51 52 public String mProvider = "AndroidOpenSSL"; 53 54 private static final int DATA_SIZE = 8192; 55 private static final byte[] DATA = new byte[DATA_SIZE]; 56 57 static { 58 for (int i = 0; i < DATA_SIZE; i++) { 59 DATA[i] = (byte) i; 60 } 61 } 62 63 private static final int LARGE_DATA_SIZE = 256 * 1024; 64 private static final byte[] LARGE_DATA = new byte[LARGE_DATA_SIZE]; 65 66 static { 67 for (int i = 0; i < LARGE_DATA_SIZE; i++) { 68 LARGE_DATA[i] = (byte) i; 69 } 70 } 71 72 private static final ByteBuffer SMALL_BUFFER = ByteBuffer.wrap(DATA); 73 private static final ByteBuffer SMALL_DIRECT_BUFFER = ByteBuffer.allocateDirect(DATA_SIZE); 74 75 static { 76 SMALL_DIRECT_BUFFER.put(DATA); SMALL_DIRECT_BUFFER.flip()77 SMALL_DIRECT_BUFFER.flip(); 78 } 79 80 private static final ByteBuffer LARGE_BUFFER = ByteBuffer.wrap(LARGE_DATA); 81 private static final ByteBuffer LARGE_DIRECT_BUFFER = 82 ByteBuffer.allocateDirect(LARGE_DATA_SIZE); 83 84 static { 85 LARGE_DIRECT_BUFFER.put(LARGE_DATA); LARGE_DIRECT_BUFFER.flip()86 LARGE_DIRECT_BUFFER.flip(); 87 } 88 89 public enum Algorithm { 90 MD5, 91 SHA1, 92 SHA256, 93 SHA384, 94 SHA512 95 }; 96 97 @Test 98 @Parameters(method = "getData") time(Algorithm algorithm)99 public void time(Algorithm algorithm) throws Exception { 100 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 101 while (state.keepRunning()) { 102 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 103 digest.update(DATA, 0, DATA_SIZE); 104 digest.digest(); 105 } 106 } 107 108 @Test 109 @Parameters(method = "getData") timeLargeArray(Algorithm algorithm)110 public void timeLargeArray(Algorithm algorithm) throws Exception { 111 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 112 while (state.keepRunning()) { 113 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 114 digest.update(LARGE_DATA, 0, LARGE_DATA_SIZE); 115 digest.digest(); 116 } 117 } 118 119 @Test 120 @Parameters(method = "getData") timeSmallChunkOfLargeArray(Algorithm algorithm)121 public void timeSmallChunkOfLargeArray(Algorithm algorithm) throws Exception { 122 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 123 while (state.keepRunning()) { 124 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 125 digest.update(LARGE_DATA, LARGE_DATA_SIZE / 2, DATA_SIZE); 126 digest.digest(); 127 } 128 } 129 130 @Test 131 @Parameters(method = "getData") timeSmallByteBuffer(Algorithm algorithm)132 public void timeSmallByteBuffer(Algorithm algorithm) throws Exception { 133 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 134 while (state.keepRunning()) { 135 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 136 SMALL_BUFFER.position(0); 137 SMALL_BUFFER.limit(SMALL_BUFFER.capacity()); 138 digest.update(SMALL_BUFFER); 139 digest.digest(); 140 } 141 } 142 143 @Test 144 @Parameters(method = "getData") timeSmallDirectByteBuffer(Algorithm algorithm)145 public void timeSmallDirectByteBuffer(Algorithm algorithm) throws Exception { 146 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 147 while (state.keepRunning()) { 148 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 149 SMALL_DIRECT_BUFFER.position(0); 150 SMALL_DIRECT_BUFFER.limit(SMALL_DIRECT_BUFFER.capacity()); 151 digest.update(SMALL_DIRECT_BUFFER); 152 digest.digest(); 153 } 154 } 155 156 @Test 157 @Parameters(method = "getData") timeLargeByteBuffer(Algorithm algorithm)158 public void timeLargeByteBuffer(Algorithm algorithm) throws Exception { 159 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 160 while (state.keepRunning()) { 161 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 162 LARGE_BUFFER.position(0); 163 LARGE_BUFFER.limit(LARGE_BUFFER.capacity()); 164 digest.update(LARGE_BUFFER); 165 digest.digest(); 166 } 167 } 168 169 @Test 170 @Parameters(method = "getData") timeLargeDirectByteBuffer(Algorithm algorithm)171 public void timeLargeDirectByteBuffer(Algorithm algorithm) throws Exception { 172 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 173 while (state.keepRunning()) { 174 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 175 LARGE_DIRECT_BUFFER.position(0); 176 LARGE_DIRECT_BUFFER.limit(LARGE_DIRECT_BUFFER.capacity()); 177 digest.update(LARGE_DIRECT_BUFFER); 178 digest.digest(); 179 } 180 } 181 182 @Test 183 @Parameters(method = "getData") timeSmallChunkOfLargeByteBuffer(Algorithm algorithm)184 public void timeSmallChunkOfLargeByteBuffer(Algorithm algorithm) throws Exception { 185 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 186 while (state.keepRunning()) { 187 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 188 LARGE_BUFFER.position(LARGE_BUFFER.capacity() / 2); 189 LARGE_BUFFER.limit(LARGE_BUFFER.position() + DATA_SIZE); 190 digest.update(LARGE_BUFFER); 191 digest.digest(); 192 } 193 } 194 195 @Test 196 @Parameters(method = "getData") timeSmallChunkOfLargeDirectByteBuffer(Algorithm algorithm)197 public void timeSmallChunkOfLargeDirectByteBuffer(Algorithm algorithm) throws Exception { 198 BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 199 while (state.keepRunning()) { 200 MessageDigest digest = MessageDigest.getInstance(algorithm.toString(), mProvider); 201 LARGE_DIRECT_BUFFER.position(LARGE_DIRECT_BUFFER.capacity() / 2); 202 LARGE_DIRECT_BUFFER.limit(LARGE_DIRECT_BUFFER.position() + DATA_SIZE); 203 digest.update(LARGE_DIRECT_BUFFER); 204 digest.digest(); 205 } 206 } 207 } 208