Updated the Android benchmark with more accurate timing and better results output. Also fixed walking the tree to use a consistent order to make comparison between the device and emulator easier.

git-svn-id: https://zxing.googlecode.com/svn/trunk@644 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
dswitkin 2008-10-27 16:30:36 +00:00
parent a1deb27f46
commit 21e7813a60
3 changed files with 40 additions and 28 deletions

View file

@ -24,7 +24,6 @@ import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.zxing.BarcodeFormat;
import java.util.Vector;
@ -82,11 +81,7 @@ public class BenchmarkActivity extends Activity {
for (int x = 0; x < items.size(); x++) {
BenchmarkItem item = items.get(x);
if (item != null) {
BarcodeFormat format = item.getFormat();
Log.v(TAG, (item.getDecoded() ? "DECODED: " : "FAILED: ") + item.getPath());
Log.v(TAG, " Ran " + item.getCount() + " tests on " +
(format != null ? format.toString() : "unknown") + " format with an average of " +
item.getAverageMilliseconds() + " ms");
Log.v(TAG, item.toString());
count++;
}
}

View file

@ -28,14 +28,13 @@ public class BenchmarkItem {
public BenchmarkItem(String path, int runs) {
mPath = path;
assert(runs > 0);
mTimes = new int[runs];
mPosition = 0;
mDecoded = false;
mFormat = null;
}
// I'm storing these separately instead of as a running total so I can add features like
// calculating the min and max later, or ignoring outliers.
public void addResult(int milliseconds) {
mTimes[mPosition] = milliseconds;
mPosition++;
@ -49,16 +48,40 @@ public class BenchmarkItem {
mFormat = format;
}
public String getPath() {
return mPath;
@Override
public String toString() {
StringBuffer result = new StringBuffer();
result.append(mDecoded ? ("DECODED " + mFormat.toString() + ": ") : "FAILED: ");
result.append(mPath);
result.append(" (");
result.append(getAverageTime());
result.append(" ms average)\n ");
int size = mTimes.length;
for (int x = 0; x < size; x++) {
result.append(mTimes[x]);
result.append(" ");
}
return result.toString();
}
public int getAverageMilliseconds() {
/**
* Calculates the average time but throws out the maximum as an outlier first.
*
* @return The average decoding time in milliseconds.
*/
private int getAverageTime() {
int size = mTimes.length;
int total = 0;
int max = mTimes[0];
for (int x = 0; x < size; x++) {
total += mTimes[x];
int time = mTimes[x];
total += time;
if (time > max) {
max = time;
}
}
total -= max;
size--;
if (size > 0) {
return total / size;
} else {
@ -66,16 +89,4 @@ public class BenchmarkItem {
}
}
public int getCount() {
return mTimes.length;
}
public boolean getDecoded() {
return mDecoded;
}
public BarcodeFormat getFormat() {
return mFormat;
}
}

View file

@ -16,6 +16,7 @@
package com.google.zxing.client.androidtest;
import android.os.Debug;
import android.os.Message;
import android.util.Log;
import com.google.zxing.MultiFormatReader;
@ -24,7 +25,7 @@ import com.google.zxing.Result;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.Arrays;
import java.util.Vector;
final class BenchmarkThread extends Thread {
@ -45,6 +46,8 @@ final class BenchmarkThread extends Thread {
public void run() {
mMultiFormatReader = new MultiFormatReader();
mMultiFormatReader.setHints(null);
// Try to get in a known state before starting the benchmark
System.gc();
Vector<BenchmarkItem> items = new Vector<BenchmarkItem>();
walkTree(mPath, items);
@ -58,6 +61,7 @@ final class BenchmarkThread extends Thread {
File file = new File(path);
if (file.isDirectory()) {
String[] files = file.list();
Arrays.sort(files);
for (int x = 0; x < files.length; x++) {
walkTree(file.getAbsolutePath() + "/" + files[x], items);
}
@ -80,21 +84,23 @@ final class BenchmarkThread extends Thread {
BenchmarkItem item = new BenchmarkItem(path, RUNS);
for (int x = 0; x < RUNS; x++) {
Date startDate = new Date();
boolean success;
Result result = null;
// Using this call instead of getting the time should eliminate a lot of variability due to
// scheduling and what else is happening in the system.
long now = Debug.threadCpuTimeNanos();
try {
result = mMultiFormatReader.decodeWithState(source);
success = true;
} catch (ReaderException e) {
success = false;
}
Date endDate = new Date();
now = Debug.threadCpuTimeNanos() - now;
if (x == 0) {
item.setDecoded(success);
item.setFormat(result != null ? result.getBarcodeFormat() : null);
}
item.addResult((int) (endDate.getTime() - startDate.getTime()));
item.addResult((int) (now / 1000));
}
return item;
}