BenchmarkState.java revision 62e5fea8554aa61bbf691e8084b8ddd68e69c78e
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;
2223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhuimport android.util.Log;
2323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
2423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhuimport java.util.ArrayList;
2523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhuimport java.util.Collections;
2662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reckimport java.util.concurrent.TimeUnit;
2723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
2823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu/**
2923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * Provides a benchmark framework.
3023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *
3123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * Example usage:
3223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * // Executes the code while keepRunning returning true.
3323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *
3423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * public void sampleMethod() {
3523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *     BenchmarkState state = new BenchmarkState();
3623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *
3723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *     int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
3823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *     while (state.keepRunning()) {
3923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *         int[] dest = new int[src.length];
4023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *         System.arraycopy(src, 0, dest, 0, src.length);
4123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *     }
4223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu *     System.out.println(state.summaryLine());
4323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu * }
4423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu */
4562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reckpublic final class BenchmarkState {
4623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private static final String TAG = "BenchmarkState";
4723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
4862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final int NOT_STARTED = 0;  // The benchmark has not started yet.
4962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final int WARMUP = 1; // The benchmark is warming up.
5023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private static final int RUNNING = 2;  // The benchmark is running.
512a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    private static final int RUNNING_PAUSED = 3;  // The benchmark is temporary paused.
522a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    private static final int FINISHED = 4;  // The benchmark has stopped.
5323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
5423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private int mState = NOT_STARTED;  // Current benchmark state.
5523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
5662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final long WARMUP_DURATION_NS = ms2ns(250); // warm-up for at least 250ms
5762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final int WARMUP_MIN_ITERATIONS = 16; // minimum iterations to warm-up for
5862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck
5962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    // TODO: Tune these values.
6062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final long TARGET_TEST_DURATION_NS = ms2ns(500); // target testing for 500 ms
6162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final int MAX_TEST_ITERATIONS = 1000000;
6262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final int MIN_TEST_ITERATIONS = 100;
6362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final int REPEAT_COUNT = 5;
6462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck
6562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private long mStartTimeNs = 0;  // Previously captured System.nanoTime().
6662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private long mPausedTimeNs = 0; // The System.nanoTime() when the pauseTiming() is called.
6762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private long mPausedDurationNs = 0;  // The duration of paused state in nano sec.
6862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck
6962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private int mIteration = 0;
7062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private int mMaxIterations = 0;
7162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck
7262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private int mRepeatCount = 0;
7323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
7423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    // Statistics. These values will be filled when the benchmark has finished.
7523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    // The computation needs double precision, but long int is fine for final reporting.
7623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private long mMedian = 0;
7723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private double mMean = 0.0;
7823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private double mStandardDeviation = 0.0;
7962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private long mMin = 0;
8053c23fdd5cf454c0f035e307ed5fda673b8b62ddSudheer Shanka
8123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    // Individual duration in nano seconds.
8223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private ArrayList<Long> mResults = new ArrayList<>();
8323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
8462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private static final long ms2ns(long ms) {
8562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        return TimeUnit.MILLISECONDS.toNanos(ms);
8653c23fdd5cf454c0f035e307ed5fda673b8b62ddSudheer Shanka    }
8753c23fdd5cf454c0f035e307ed5fda673b8b62ddSudheer Shanka
8853c23fdd5cf454c0f035e307ed5fda673b8b62ddSudheer Shanka    /**
8923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu     * Calculates statistics.
9023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu     */
9123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private void calculateSatistics() {
9223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        final int size = mResults.size();
9323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        if (size <= 1) {
9423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            throw new IllegalStateException("At least two results are necessary.");
9523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        }
9623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
9723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        Collections.sort(mResults);
9823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        mMedian = size % 2 == 0 ? (mResults.get(size / 2) + mResults.get(size / 2 + 1)) / 2 :
9923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu                mResults.get(size / 2);
10023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
10162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mMin = mResults.get(0);
10223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        for (int i = 0; i < size; ++i) {
10362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            long result = mResults.get(i);
10462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            mMean += result;
10562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            if (result < mMin) {
10662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                mMin = result;
10762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            }
10823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        }
10923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        mMean /= (double) size;
11023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
11123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        for (int i = 0; i < size; ++i) {
11223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            final double tmp = mResults.get(i) - mMean;
11323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            mStandardDeviation += tmp * tmp;
11423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        }
11523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        mStandardDeviation = Math.sqrt(mStandardDeviation / (double) (size - 1));
11623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    }
11723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
1182a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    // Stops the benchmark timer.
1192a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    // This method can be called only when the timer is running.
1202a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    public void pauseTiming() {
1212a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka        if (mState == RUNNING_PAUSED) {
1222a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka            throw new IllegalStateException(
1232a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka                    "Unable to pause the benchmark. The benchmark has already paused.");
1242a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka        }
12562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mPausedTimeNs = System.nanoTime();
1262a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka        mState = RUNNING_PAUSED;
1272a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    }
1282a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka
1292a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    // Starts the benchmark timer.
1302a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    // This method can be called only when the timer is stopped.
1312a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    public void resumeTiming() {
1322a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka        if (mState == RUNNING) {
1332a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka            throw new IllegalStateException(
1342a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka                    "Unable to resume the benchmark. The benchmark is already running.");
1352a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka        }
13662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mPausedDurationNs += System.nanoTime() - mPausedTimeNs;
13762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mPausedTimeNs = 0;
13862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mState = RUNNING;
13962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    }
14062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck
14162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private void beginWarmup() {
14262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mStartTimeNs = System.nanoTime();
14362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mIteration = 0;
14462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mState = WARMUP;
14562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    }
14662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck
14762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private void beginBenchmark(long warmupDuration, int iterations) {
14862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations));
14962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mMaxIterations = Math.min(MAX_TEST_ITERATIONS,
15062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                Math.max(mMaxIterations, MIN_TEST_ITERATIONS));
15162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mPausedDurationNs = 0;
15262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mIteration = 0;
15362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mRepeatCount = 0;
1542a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka        mState = RUNNING;
15562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mStartTimeNs = System.nanoTime();
15662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    }
15762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck
15862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private boolean startNextTestRun() {
15962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        final long currentTime = System.nanoTime();
16062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mResults.add((currentTime - mStartTimeNs - mPausedDurationNs) / mMaxIterations);
16162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mRepeatCount++;
16262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        if (mRepeatCount >= REPEAT_COUNT) {
16362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            calculateSatistics();
16462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            mState = FINISHED;
16562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            return false;
16662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        }
16762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mPausedDurationNs = 0;
16862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mIteration = 0;
16962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        mStartTimeNs = System.nanoTime();
17062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        return true;
1712a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka    }
1722a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka
17323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    /**
17423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu     * Judges whether the benchmark needs more samples.
17523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu     *
17623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu     * For the usage, see class comment.
17723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu     */
17823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    public boolean keepRunning() {
17923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        switch (mState) {
18023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            case NOT_STARTED:
18162e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                beginWarmup();
18262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                return true;
18362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            case WARMUP:
18462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                mIteration++;
18562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                // Only check nanoTime on every iteration in WARMUP since we
18662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                // don't yet have a target iteration count.
18762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                final long duration = System.nanoTime() - mStartTimeNs;
18862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                if (mIteration >= WARMUP_MIN_ITERATIONS && duration >= WARMUP_DURATION_NS) {
18962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                    beginBenchmark(duration, mIteration);
19062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                }
19123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu                return true;
19223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            case RUNNING:
19362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                mIteration++;
19462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                if (mIteration >= mMaxIterations) {
19562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck                    return startNextTestRun();
19623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu                }
19723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu                return true;
1982a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka            case RUNNING_PAUSED:
1992a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka                throw new IllegalStateException(
2002a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka                        "Benchmark step finished with paused state. " +
2012a154e2940e79f694ff95b93012e56c5ade70234Seigo Nonaka                        "Resume the benchmark before finishing each step.");
20223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            case FINISHED:
20323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu                throw new IllegalStateException("The benchmark has finished.");
20423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            default:
20523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu                throw new IllegalStateException("The benchmark is in unknown state.");
20623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        }
20723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    }
20823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
20962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private long mean() {
21023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        if (mState != FINISHED) {
21123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            throw new IllegalStateException("The benchmark hasn't finished");
21223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        }
21323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        return (long) mMean;
21423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    }
21523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
21662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private long median() {
21723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        if (mState != FINISHED) {
21823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            throw new IllegalStateException("The benchmark hasn't finished");
21923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        }
22023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        return mMedian;
22123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    }
22223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
22362e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private long min() {
22462e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        if (mState != FINISHED) {
22562e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck            throw new IllegalStateException("The benchmark hasn't finished");
22662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        }
22762e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        return mMin;
22862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    }
22962e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck
23062e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck    private long standardDeviation() {
23123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        if (mState != FINISHED) {
23223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu            throw new IllegalStateException("The benchmark hasn't finished");
23323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        }
23423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        return (long) mStandardDeviation;
23523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    }
23623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
23723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    private String summaryLine() {
23823d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        StringBuilder sb = new StringBuilder();
23923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        sb.append("Summary: ");
240a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu        sb.append("median=").append(median()).append("ns, ");
241a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu        sb.append("mean=").append(mean()).append("ns, ");
24262e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        sb.append("min=").append(min()).append("ns, ");
243a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu        sb.append("sigma=").append(standardDeviation()).append(", ");
244a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu        sb.append("iteration=").append(mResults.size()).append(", ");
245a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu        // print out the first few iterations' number for double checking.
24662e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        int sampleNumber = Math.min(mResults.size(), 16);
247a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu        for (int i = 0; i < sampleNumber; i++) {
248a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu            sb.append("No ").append(i).append(" result is ").append(mResults.get(i)).append(", ");
249a9cebd628c53b900d48600a5e7ced546c91522e6Teng-Hui Zhu        }
25023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        return sb.toString();
25123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    }
25223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu
25323d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    public void sendFullStatusReport(Instrumentation instrumentation, String key) {
25423d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        Log.i(TAG, key + summaryLine());
25523d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        Bundle status = new Bundle();
25623d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        status.putLong(key + "_median", median());
25723d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        status.putLong(key + "_mean", mean());
25862e5fea8554aa61bbf691e8084b8ddd68e69c78eJohn Reck        status.putLong(key + "_min", min());
25923d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        status.putLong(key + "_standardDeviation", standardDeviation());
26023d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu        instrumentation.sendStatus(Activity.RESULT_OK, status);
26123d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu    }
26223d1fdded5fe78024927137ddfb82401fd9e3344Teng-Hui Zhu}
263