diff options
author | Dan Egnor <egnor@google.com> | 2010-04-28 18:50:16 -0700 |
---|---|---|
committer | Dan Egnor <egnor@google.com> | 2010-04-28 18:50:16 -0700 |
commit | 80df0a552ca1c8bf2eb26ee79f1ffd9a641f3564 (patch) | |
tree | 137cbd0f7fe97fac00350998e8813c1aef87fdd4 | |
parent | a31cff630e47c434b54ccb51fea15115b6e04d50 (diff) | |
download | experimental-80df0a552ca1c8bf2eb26ee79f1ffd9a641f3564.tar.gz |
Sundry RpcPerformance tweaks and modifications:
Use a fixed (user selectable) iteration count rather than a timer.
Add raw file I/O tests (of somewhat questionable precision).
Add SDK compatibility flags (needed to install on non-dev devices)
Change-Id: I63d9527fca0ba5dbe1a4d6cbceebd0bd9757ef51
-rw-r--r-- | RpcPerformance/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | RpcPerformance/res/layout/main.xml | 84 | ||||
-rw-r--r-- | RpcPerformance/src/com/android/rpc_performance/ProviderPerfActivity.java | 151 |
3 files changed, 178 insertions, 59 deletions
diff --git a/RpcPerformance/AndroidManifest.xml b/RpcPerformance/AndroidManifest.xml index a2eed36..0378a5a 100644 --- a/RpcPerformance/AndroidManifest.xml +++ b/RpcPerformance/AndroidManifest.xml @@ -6,6 +6,8 @@ <uses-permission android:name="android.permission.WRITE_SETTINGS" /> + <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="7" /> + <application android:label="RPC Performance"> <activity android:name="ProviderPerfActivity" diff --git a/RpcPerformance/res/layout/main.xml b/RpcPerformance/res/layout/main.xml index 43ebfcf..90e33d8 100644 --- a/RpcPerformance/res/layout/main.xml +++ b/RpcPerformance/res/layout/main.xml @@ -7,21 +7,38 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchColumns="true"> + + <TableRow> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Iteration count:" + /> + + <EditText android:id="@+id/iterations_edit" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:numeric="integer" + android:singleLine="true" + android:text="100" + /> + </TableRow> + <TableRow> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical"> <TextView - android:id="@+id/lookup_text" + android:id="@+id/file_read_text" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="Get Setting xproc:" + android:text="Seek + read cached:" /> <Button - android:id="@+id/lookup_button" + android:id="@+id/file_read_button" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="Reads" + android:text="File read" /> </LinearLayout> @@ -29,46 +46,82 @@ android:layout_width="wrap_content" android:orientation="vertical"> <TextView - android:id="@+id/bg_read_text" + android:id="@+id/file_write_text" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Open + write + close:" + /> + <Button + android:id="@+id/file_write_button" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="File write" + /> + </LinearLayout> + </TableRow> + + <TableRow> + <LinearLayout android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:orientation="vertical"> + <TextView + android:id="@+id/settings_read_text" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Settings read xproc:" + /> + <Button + android:id="@+id/settings_read_button" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="Settings read" + /> + </LinearLayout> + + <LinearLayout android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:orientation="vertical"> + <TextView + android:id="@+id/settings_sleep_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="... + post sleep:" /> <Button - android:id="@+id/bg_read_button" + android:id="@+id/settings_sleep_button" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="Read2" + android:text="Sleep + Read" /> </LinearLayout> </TableRow> - + <TableRow> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical"> <TextView - android:id="@+id/bg_write_text" + android:id="@+id/settings_write_text" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="Background writes:" /> + android:text="Settings write:" /> <Button - android:id="@+id/bg_write_button" + android:id="@+id/settings_write_button" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="Writes" /> + android:text="Settings write" /> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical"> <TextView - android:id="@+id/bg_writedup_text" + android:id="@+id/settings_writedup_text" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="Background dup writes:" /> + android:text="Settings dup write:" /> <Button - android:id="@+id/bg_writedup_button" + android:id="@+id/settings_writedup_button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Dup writes" /> @@ -203,7 +256,6 @@ android:text="cp.Call() no exist" /> </LinearLayout> </TableRow> - </TableLayout> </ScrollView> diff --git a/RpcPerformance/src/com/android/rpc_performance/ProviderPerfActivity.java b/RpcPerformance/src/com/android/rpc_performance/ProviderPerfActivity.java index 834dc45..a47c6b7 100644 --- a/RpcPerformance/src/com/android/rpc_performance/ProviderPerfActivity.java +++ b/RpcPerformance/src/com/android/rpc_performance/ProviderPerfActivity.java @@ -57,6 +57,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.RandomAccessFile; public class ProviderPerfActivity extends Activity { @@ -85,7 +86,8 @@ public class ProviderPerfActivity extends Activity { }; - ContentResolver cr; + private ContentResolver cr; + private int mIterations = 100; /** Called when the activity is first created. */ @Override @@ -95,31 +97,40 @@ public class ProviderPerfActivity extends Activity { cr = getContentResolver(); - setButtonAction(R.id.lookup_button, new Runnable() { + setButtonAction(R.id.file_read_button, new Runnable() { public void run() { - final float avgTime = settingsProviderLoop(100, MODE_READ, 0); - endAsyncOp(R.id.lookup_button, R.id.lookup_text, avgTime); + final float avgTime = fileReadLoop(); + endAsyncOp(R.id.file_read_button, R.id.file_read_text, avgTime); }}); - setButtonAction(R.id.bg_read_button, new Runnable() { + setButtonAction(R.id.file_write_button, new Runnable() { public void run() { - final float avgTime = - settingsProviderLoop(50, MODE_READ, 100); - endAsyncOp(R.id.bg_read_button, R.id.bg_read_text, avgTime); + final float avgTime = fileWriteLoop(); + endAsyncOp(R.id.file_write_button, R.id.file_write_text, avgTime); }}); - setButtonAction(R.id.bg_write_button, new Runnable() { + setButtonAction(R.id.settings_read_button, new Runnable() { public void run() { - final float avgTime = - settingsProviderLoop(20, MODE_WRITE, 0); - endAsyncOp(R.id.bg_write_button, R.id.bg_write_text, avgTime); + final float avgTime = settingsProviderLoop(MODE_READ, 0); + endAsyncOp(R.id.settings_read_button, R.id.settings_read_text, avgTime); }}); - setButtonAction(R.id.bg_writedup_button, new Runnable() { + setButtonAction(R.id.settings_sleep_button, new Runnable() { public void run() { - final float avgTime = - settingsProviderLoop(20, MODE_WRITE_DUP, 0); - endAsyncOp(R.id.bg_writedup_button, R.id.bg_writedup_text, avgTime); + final float avgTime = settingsProviderLoop(MODE_READ, 100); + endAsyncOp(R.id.settings_sleep_button, R.id.settings_sleep_text, avgTime); + }}); + + setButtonAction(R.id.settings_write_button, new Runnable() { + public void run() { + final float avgTime = settingsProviderLoop(MODE_WRITE, 0); + endAsyncOp(R.id.settings_write_button, R.id.settings_write_text, avgTime); + }}); + + setButtonAction(R.id.settings_writedup_button, new Runnable() { + public void run() { + final float avgTime = settingsProviderLoop(MODE_WRITE_DUP, 0); + endAsyncOp(R.id.settings_writedup_button, R.id.settings_writedup_text, avgTime); }}); setButtonAction(R.id.dummy_lookup_button, new Runnable() { @@ -194,6 +205,16 @@ public class ProviderPerfActivity extends Activity { } button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { + TextView tv = (TextView) findViewById(R.id.iterations_edit); + if (tv != null) { + try { + mIterations = Integer.parseInt(tv.getText().toString()); + } catch (NumberFormatException e) { + Log.w(TAG, "Invalid iteration count", e); + if (tv != null) tv.setText(Integer.toString(mIterations)); + } + } + button.setEnabled(false); new Thread(r).start(); } @@ -217,14 +238,67 @@ public class ProviderPerfActivity extends Activity { tv.setText(text); } + private float fileReadLoop() { + RandomAccessFile raf = null; + File filename = getFileStreamPath("test.dat"); + try { + long sumNanos = 0; + byte[] buf = new byte[512]; + + raf = new RandomAccessFile(filename, "rw"); + raf.write(buf); + raf.close(); + raf = null; + + // The data's almost certainly cached -- it's not clear what we're testing here + raf = new RandomAccessFile(filename, "r"); + for (int i = 0; i < mIterations; i++) { + long lastTime = System.nanoTime(); + raf.seek(0); + raf.read(buf); + sumNanos += System.nanoTime() - lastTime; + } + + return (float) sumNanos / Math.max(1.0f, (float) mIterations) / 1000000.0f; + } catch (IOException e) { + Log.e(TAG, "File read failed", e); + return 0; + } finally { + try { if (raf != null) raf.close(); } catch (IOException e) {} + } + } + + private float fileWriteLoop() { + RandomAccessFile raf = null; + File filename = getFileStreamPath("test.dat"); + try { + long sumNanos = 0; + byte[] buf = new byte[512]; + for (int i = 0; i < mIterations; i++) { + for (int j = 0; j < buf.length; j++) buf[j] = (byte) (i + j); + long lastTime = System.nanoTime(); + raf = new RandomAccessFile(filename, "rw"); + raf.write(buf); + raf.close(); + raf = null; + sumNanos += System.nanoTime() - lastTime; + } + + return (float) sumNanos / Math.max(1.0f, (float) mIterations) / 1000000.0f; + } catch (IOException e) { + Log.e(TAG, "File read failed", e); + return 0; + } finally { + try { if (raf != null) raf.close(); } catch (IOException e) {} + } + } + // Returns average cross-process dummy query time in milliseconds. private float noOpProviderLoop(Uri uri) { long sumNanos = 0; int failures = 0; int total = 0; - long startTime = System.nanoTime(); - long endTime = startTime + LOOP_TIME_NANOS; - while (System.nanoTime() < endTime) { + for (int i = 0; i < mIterations; i++) { long duration = doNoOpLookup(uri); if (duration < 0) { failures++; @@ -247,15 +321,13 @@ public class ProviderPerfActivity extends Activity { long sumNanos = 0; int total = 0; - long lastTime = System.nanoTime(); - long endTime = lastTime + LOOP_TIME_NANOS; try { - while (lastTime < endTime) { + for (int i = 0; i < mIterations; i++) { + long lastTime = System.nanoTime(); Bundle b = cp.call("GET_system", key, null); long nowTime = System.nanoTime(); total++; sumNanos += (nowTime - lastTime); - lastTime = nowTime; } } catch (RemoteException e) { return -999.0f; @@ -267,17 +339,16 @@ public class ProviderPerfActivity extends Activity { return averageMillis; } - // Returns average cross-process dummy query time in milliseconds. + // Returns average time to read a /proc file in milliseconds. private float procLoop() { long sumNanos = 0; int total = 0; - long lastTime = System.nanoTime(); - long endTime = lastTime + LOOP_TIME_NANOS; File f = new File("/proc/self/cmdline"); byte[] buf = new byte[100]; String value = null; try { - while (lastTime < endTime) { + for (int i = 0; i < mIterations; i++) { + long lastTime = System.nanoTime(); FileInputStream is = new FileInputStream(f); int readBytes = is.read(buf, 0, 100); is.close(); @@ -335,9 +406,8 @@ public class ProviderPerfActivity extends Activity { try { long sumNanos = 0; int count = 0; - long lastTime = System.nanoTime(); - long endTime = lastTime + LOOP_TIME_NANOS; - while (lastTime < endTime) { + for (int i = 0; i < mIterations; i++) { + long lastTime = System.nanoTime(); if (amtEncoding == 0) { mServiceStub.pingVoid(); } else { @@ -345,7 +415,6 @@ public class ProviderPerfActivity extends Activity { } long curTime = System.nanoTime(); long duration = curTime - lastTime; - lastTime = curTime; count++; sumNanos += duration; } @@ -369,18 +438,16 @@ public class ProviderPerfActivity extends Activity { InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); - long nowTime = System.nanoTime(); - long endTime = nowTime + LOOP_TIME_NANOS; int count = 0; long sumNanos = 0; - while (nowTime < endTime) { + for (int i = 0; i < mIterations; i++) { + long beforeTime = System.nanoTime(); int expectByte = count & 0xff; os.write(expectByte); int gotBackByte = is.read(); long afterTime = System.nanoTime(); - sumNanos += (afterTime - nowTime); - nowTime = afterTime; + sumNanos += (afterTime - beforeTime); if (gotBackByte != expectByte) { Log.w(TAG, "Got wrong byte back. Got: " + gotBackByte @@ -405,13 +472,11 @@ public class ProviderPerfActivity extends Activity { private static final int MODE_WRITE = 1; private static final int MODE_WRITE_DUP = 2; - private float settingsProviderLoop(int iters, int mode, long innerSleep) { + private float settingsProviderLoop(int mode, long innerSleep) { long sumMillis = 0; int total = 0; - long startTime = System.nanoTime(); - long endTime = startTime + LOOP_TIME_NANOS; - while (System.nanoTime() < endTime) { - long duration = mode == MODE_READ ? doRead(innerSleep) : doWrite(mode); + for (int i = 0; i < mIterations; i++) { + long duration = mode == MODE_READ ? settingsRead(innerSleep) : settingsWrite(mode); if (duration < 0) { return -999.0f; } @@ -425,7 +490,7 @@ public class ProviderPerfActivity extends Activity { } // Returns milliseconds taken, or -1 on failure. - private long doRead(long innerSleep) { + private long settingsRead(long innerSleep) { Cursor c = null; try { long startTime = SystemClock.uptimeMillis(); @@ -455,7 +520,7 @@ public class ProviderPerfActivity extends Activity { } // Returns milliseconds taken, or -1 on failure. - private long doWrite(int mode) { + private long settingsWrite(int mode) { Cursor c = null; long startTime = SystemClock.uptimeMillis(); // The database will take care of replacing duplicates. |