123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu/* 223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * Copyright (C) 2016 The Android Open Source Project 323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * 423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * you may not use this file except in compliance with the License. 623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * You may obtain a copy of the License at 723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * 823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * http://www.apache.org/licenses/LICENSE-2.0 923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * 1023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * Unless required by applicable law or agreed to in writing, software 1123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * distributed under the License is distributed on an "AS IS" BASIS, 1223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * See the License for the specific language governing permissions and 1423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * limitations under the License. 1523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu */ 1623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 1723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhupackage android.perftests.utils; 1823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 1923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhuimport android.app.Activity; 2023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhuimport android.app.Instrumentation; 2123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhuimport android.os.Bundle; 223acf0382da22cda88234e599cd81b1ff5441cc35John Reckimport android.os.Debug; 233acf0382da22cda88234e599cd81b1ff5441cc35John Reckimport android.support.test.InstrumentationRegistry; 2423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhuimport android.util.Log; 2523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 263acf0382da22cda88234e599cd81b1ff5441cc35John Reckimport java.io.File; 2723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhuimport java.util.ArrayList; 2862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reckimport java.util.concurrent.TimeUnit; 2923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 3023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu/** 3123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * Provides a benchmark framework. 3223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * 3323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * Example usage: 3423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * // Executes the code while keepRunning returning true. 3523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * 3623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * public void sampleMethod() { 3723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * BenchmarkState state = new BenchmarkState(); 3823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * 3923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 4023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * while (state.keepRunning()) { 4123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * int[] dest = new int[src.length]; 4223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * System.arraycopy(src, 0, dest, 0, src.length); 4323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * } 4423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * System.out.println(state.summaryLine()); 4523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * } 4623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu */ 4762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reckpublic final class BenchmarkState { 48c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck 4923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu private static final String TAG = "BenchmarkState"; 503acf0382da22cda88234e599cd81b1ff5441cc35John Reck private static final boolean ENABLE_PROFILING = false; 5123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 5262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private static final int NOT_STARTED = 0; // The benchmark has not started yet. 5362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private static final int WARMUP = 1; // The benchmark is warming up. 5423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu private static final int RUNNING = 2; // The benchmark is running. 55c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck private static final int FINISHED = 3; // The benchmark has stopped. 5623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 5723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu private int mState = NOT_STARTED; // Current benchmark state. 5823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 5962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private static final long WARMUP_DURATION_NS = ms2ns(250); // warm-up for at least 250ms 6062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private static final int WARMUP_MIN_ITERATIONS = 16; // minimum iterations to warm-up for 6162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck 6262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck // TODO: Tune these values. 6362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private static final long TARGET_TEST_DURATION_NS = ms2ns(500); // target testing for 500 ms 6462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private static final int MAX_TEST_ITERATIONS = 1000000; 6524e98b7667da2ba7718e111c4b6d5d739e67e4f4John Reck private static final int MIN_TEST_ITERATIONS = 10; 6662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private static final int REPEAT_COUNT = 5; 6762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck 6862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private long mStartTimeNs = 0; // Previously captured System.nanoTime(). 69c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck private boolean mPaused; 7062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private long mPausedTimeNs = 0; // The System.nanoTime() when the pauseTiming() is called. 7162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private long mPausedDurationNs = 0; // The duration of paused state in nano sec. 7262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck 7362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private int mIteration = 0; 7462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private int mMaxIterations = 0; 7562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck 7662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private int mRepeatCount = 0; 7723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 7823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu // Statistics. These values will be filled when the benchmark has finished. 7923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu // The computation needs double precision, but long int is fine for final reporting. 80263d674d598f77a1f91bdfc73be808efd3446133Arthur Eubanks private Stats mStats; 8153c23fdd5cf454c0f035e307ed5fda673b8b62ddSudheer Shanka 8223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu // Individual duration in nano seconds. 8323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu private ArrayList<Long> mResults = new ArrayList<>(); 8423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 8562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private static final long ms2ns(long ms) { 8662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck return TimeUnit.MILLISECONDS.toNanos(ms); 8753c23fdd5cf454c0f035e307ed5fda673b8b62ddSudheer Shanka } 8853c23fdd5cf454c0f035e307ed5fda673b8b62ddSudheer Shanka 892a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka // Stops the benchmark timer. 902a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka // This method can be called only when the timer is running. 912a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka public void pauseTiming() { 92c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck if (mPaused) { 932a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka throw new IllegalStateException( 942a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka "Unable to pause the benchmark. The benchmark has already paused."); 952a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka } 9662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mPausedTimeNs = System.nanoTime(); 97c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck mPaused = true; 982a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka } 992a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka 1002a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka // Starts the benchmark timer. 1012a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka // This method can be called only when the timer is stopped. 1022a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka public void resumeTiming() { 103c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck if (!mPaused) { 1042a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka throw new IllegalStateException( 1052a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka "Unable to resume the benchmark. The benchmark is already running."); 1062a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka } 10762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mPausedDurationNs += System.nanoTime() - mPausedTimeNs; 10862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mPausedTimeNs = 0; 109c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck mPaused = false; 11062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck } 11162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck 11262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private void beginWarmup() { 11362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mStartTimeNs = System.nanoTime(); 11462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mIteration = 0; 11562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mState = WARMUP; 11662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck } 11762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck 11862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private void beginBenchmark(long warmupDuration, int iterations) { 1193acf0382da22cda88234e599cd81b1ff5441cc35John Reck if (ENABLE_PROFILING) { 1203acf0382da22cda88234e599cd81b1ff5441cc35John Reck File f = new File(InstrumentationRegistry.getContext().getDataDir(), "benchprof"); 1213acf0382da22cda88234e599cd81b1ff5441cc35John Reck Log.d(TAG, "Tracing to: " + f.getAbsolutePath()); 1223acf0382da22cda88234e599cd81b1ff5441cc35John Reck Debug.startMethodTracingSampling(f.getAbsolutePath(), 16 * 1024 * 1024, 100); 1233acf0382da22cda88234e599cd81b1ff5441cc35John Reck } 12462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations)); 12562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mMaxIterations = Math.min(MAX_TEST_ITERATIONS, 12662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck Math.max(mMaxIterations, MIN_TEST_ITERATIONS)); 12762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mPausedDurationNs = 0; 12862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mIteration = 0; 12962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mRepeatCount = 0; 1302a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka mState = RUNNING; 13162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mStartTimeNs = System.nanoTime(); 13262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck } 13362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck 13462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private boolean startNextTestRun() { 13562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck final long currentTime = System.nanoTime(); 13662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mResults.add((currentTime - mStartTimeNs - mPausedDurationNs) / mMaxIterations); 13762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mRepeatCount++; 13862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck if (mRepeatCount >= REPEAT_COUNT) { 1393acf0382da22cda88234e599cd81b1ff5441cc35John Reck if (ENABLE_PROFILING) { 1403acf0382da22cda88234e599cd81b1ff5441cc35John Reck Debug.stopMethodTracing(); 1413acf0382da22cda88234e599cd81b1ff5441cc35John Reck } 142263d674d598f77a1f91bdfc73be808efd3446133Arthur Eubanks mStats = new Stats(mResults); 14362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mState = FINISHED; 14462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck return false; 14562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck } 14662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mPausedDurationNs = 0; 14762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mIteration = 0; 14862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mStartTimeNs = System.nanoTime(); 14962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck return true; 1502a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka } 1512a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka 15223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu /** 15323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * Judges whether the benchmark needs more samples. 15423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * 15523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * For the usage, see class comment. 15623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu */ 15723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu public boolean keepRunning() { 15823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu switch (mState) { 15923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu case NOT_STARTED: 16062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck beginWarmup(); 16162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck return true; 16262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck case WARMUP: 16362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mIteration++; 16462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck // Only check nanoTime on every iteration in WARMUP since we 16562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck // don't yet have a target iteration count. 16662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck final long duration = System.nanoTime() - mStartTimeNs; 16762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck if (mIteration >= WARMUP_MIN_ITERATIONS && duration >= WARMUP_DURATION_NS) { 16862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck beginBenchmark(duration, mIteration); 16962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck } 17023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu return true; 17123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu case RUNNING: 17262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck mIteration++; 17362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck if (mIteration >= mMaxIterations) { 17462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck return startNextTestRun(); 17523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 176c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck if (mPaused) { 177c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck throw new IllegalStateException( 178c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck "Benchmark step finished with paused state. " + 179c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck "Resume the benchmark before finishing each step."); 180c1d6ba4053b4d5f7a9c3c255073d22fbe4af392fJohn Reck } 18123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu return true; 18223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu case FINISHED: 18323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu throw new IllegalStateException("The benchmark has finished."); 18423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu default: 18523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu throw new IllegalStateException("The benchmark is in unknown state."); 18623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 18723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 18823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 18962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private long mean() { 19023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu if (mState != FINISHED) { 19123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu throw new IllegalStateException("The benchmark hasn't finished"); 19223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 193263d674d598f77a1f91bdfc73be808efd3446133Arthur Eubanks return (long) mStats.getMean(); 19423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 19523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 19662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private long median() { 19723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu if (mState != FINISHED) { 19823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu throw new IllegalStateException("The benchmark hasn't finished"); 19923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 200263d674d598f77a1f91bdfc73be808efd3446133Arthur Eubanks return mStats.getMedian(); 20123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 20223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 20362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private long min() { 20462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck if (mState != FINISHED) { 20562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck throw new IllegalStateException("The benchmark hasn't finished"); 20662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck } 207263d674d598f77a1f91bdfc73be808efd3446133Arthur Eubanks return mStats.getMin(); 20862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck } 20962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck 21062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck private long standardDeviation() { 21123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu if (mState != FINISHED) { 21223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu throw new IllegalStateException("The benchmark hasn't finished"); 21323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 214263d674d598f77a1f91bdfc73be808efd3446133Arthur Eubanks return (long) mStats.getStandardDeviation(); 21523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 21623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 21723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu private String summaryLine() { 21823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu StringBuilder sb = new StringBuilder(); 21923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu sb.append("Summary: "); 220a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu sb.append("median=").append(median()).append("ns, "); 221a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu sb.append("mean=").append(mean()).append("ns, "); 22262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck sb.append("min=").append(min()).append("ns, "); 223a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu sb.append("sigma=").append(standardDeviation()).append(", "); 224a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu sb.append("iteration=").append(mResults.size()).append(", "); 225a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu // print out the first few iterations' number for double checking. 22662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck int sampleNumber = Math.min(mResults.size(), 16); 227a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu for (int i = 0; i < sampleNumber; i++) { 228a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu sb.append("No ").append(i).append(" result is ").append(mResults.get(i)).append(", "); 229a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu } 23023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu return sb.toString(); 23123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 23223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu 23323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu public void sendFullStatusReport(Instrumentation instrumentation, String key) { 23423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu Log.i(TAG, key + summaryLine()); 23523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu Bundle status = new Bundle(); 23623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu status.putLong(key + "_median", median()); 23723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu status.putLong(key + "_mean", mean()); 23862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck status.putLong(key + "_min", min()); 23923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu status.putLong(key + "_standardDeviation", standardDeviation()); 24023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu instrumentation.sendStatus(Activity.RESULT_OK, status); 24123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu } 24223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu} 243