summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java80
-rw-r--r--core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py26
2 files changed, 97 insertions, 9 deletions
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
index bcd90600b48a..75809c0fce4b 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
@@ -18,41 +18,70 @@ package android.database;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
+import android.os.SystemProperties;
import android.test.PerformanceTestCase;
+import android.util.ArrayMap;
import android.util.Log;
import junit.framework.TestCase;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.Map;
import java.util.Random;
/**
- * Database Performance Tests
- *
+ * Database Performance Tests.
+ *
+ * <p>Usage:
+ * <code>./frameworks/base/core/tests/coretests/src/android/database/run_newdb_perf_test.sh</code>
+ * <p>Test with WAL journaling enabled:
+ * <code>setprop debug.NewDatabasePerformanceTests.enable_wal 1</code>
*/
-
public class NewDatabasePerformanceTests {
private static final String TAG = "NewDatabasePerformanceTests";
+ private static final boolean DEBUG_ENABLE_WAL = SystemProperties
+ .getBoolean("debug.NewDatabasePerformanceTests.enable_wal", false);
+
private static final int DATASET_SIZE = 100; // Size of dataset to use for testing
private static final int FAST_OP_MULTIPLIER = 25;
private static final int FAST_OP_COUNT = FAST_OP_MULTIPLIER * DATASET_SIZE;
+ private static Long sInitialWriteBytes;
+
+ static {
+ sInitialWriteBytes = getIoStats().get("write_bytes");
+ if (DEBUG_ENABLE_WAL) {
+ Log.i(TAG, "Testing with WAL enabled");
+ }
+ }
+
public static class PerformanceBase extends TestCase
- implements PerformanceTestCase {
+ implements PerformanceTestCase {
protected static final int CURRENT_DATABASE_VERSION = 42;
protected SQLiteDatabase mDatabase;
protected File mDatabaseFile;
private long mSetupFinishedTime;
+ private Long mSetupWriteBytes;
public void setUp() {
long setupStarted = System.currentTimeMillis();
mDatabaseFile = new File("/sdcard", "perf_database_test.db");
if (mDatabaseFile.exists()) {
- mDatabaseFile.delete();
+ SQLiteDatabase.deleteDatabase(mDatabaseFile);
+ }
+ SQLiteDatabase.OpenParams.Builder params = new SQLiteDatabase.OpenParams.Builder();
+ params.addOpenFlags(SQLiteDatabase.CREATE_IF_NECESSARY);
+ if (DEBUG_ENABLE_WAL) {
+ params.addOpenFlags(SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING);
+ }
+ mDatabase = SQLiteDatabase.openDatabase(mDatabaseFile, params.build());
+ if (DEBUG_ENABLE_WAL) {
+ assertTrue("Cannot enable WAL", mDatabase.isWriteAheadLoggingEnabled());
}
- mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
- assertTrue(mDatabase != null);
mDatabase.setVersion(CURRENT_DATABASE_VERSION);
mDatabase.beginTransactionNonExclusive();
prepareForTest();
@@ -61,6 +90,7 @@ public class NewDatabasePerformanceTests {
mSetupFinishedTime = System.currentTimeMillis();
Log.i(TAG, "Setup for " + getClass().getSimpleName() + " took "
+ (mSetupFinishedTime - setupStarted) + " ms");
+ mSetupWriteBytes = getIoStats().get("write_bytes");
}
protected void prepareForTest() {
@@ -70,7 +100,14 @@ public class NewDatabasePerformanceTests {
long duration = System.currentTimeMillis() - mSetupFinishedTime;
Log.i(TAG, "Test " + getClass().getSimpleName() + " took " + duration + " ms");
mDatabase.close();
- mDatabaseFile.delete();
+ SQLiteDatabase.deleteDatabase(mDatabaseFile);
+ Long writeBytes = getIoStats().get("write_bytes");
+ if (writeBytes != null && sInitialWriteBytes != null) {
+ long testWriteBytes = writeBytes - mSetupWriteBytes;
+ long totalWriteBytes = (writeBytes - sInitialWriteBytes);
+ Log.i(TAG, "Test " + getClass().getSimpleName() + " write_bytes=" + testWriteBytes
+ + ". Since tests started - totalWriteBytes=" + totalWriteBytes);
+ }
}
public boolean isPerformanceOnly() {
@@ -897,4 +934,31 @@ public class NewDatabasePerformanceTests {
static final String[] TENS =
{"", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
"seventy", "eighty", "ninety"};
+
+ static Map<String, Long> getIoStats() {
+ String ioStat = "/proc/self/io";
+ Map<String, Long> results = new ArrayMap<>();
+ try {
+ List<String> lines = Files.readAllLines(new File(ioStat).toPath());
+ for (String line : lines) {
+ line = line.trim();
+ String[] split = line.split(":");
+ if (split.length == 2) {
+ try {
+ String key = split[0].trim();
+ Long value = Long.valueOf(split[1].trim());
+ results.put(key, value);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Cannot parse number from " + line);
+ }
+ } else if (line.isEmpty()) {
+ Log.e(TAG, "Cannot parse line " + line);
+ }
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Can't read: " + ioStat, e);
+ }
+ return results;
+ }
+
}
diff --git a/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py b/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py
index 1faeceb78d8b..27b20c327c0b 100644
--- a/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py
+++ b/core/tests/coretests/src/android/database/process_newdb_perf_test_logs.py
@@ -25,7 +25,16 @@ def main():
all_lines = f.readlines()
timings = {}
running_sum = 0
+ # If WAL was enabled for the test
+ wal_enabled = False
+ # Number of bytes which test process caused to be sent to the storage layer.
+ # Reported as max value across all runs.
+ max_write_bytes = 0
for line in all_lines:
+ if "NewDatabasePerformanceTests: Testing with WAL enabled" in line:
+ wal_enabled = True
+ continue
+
regex = r"NewDatabasePerformanceTests: Test (\w+) took (\d+) ms"
matches = re.search(regex, line)
if matches:
@@ -35,16 +44,31 @@ def main():
timings[test_name] = []
timings[test_name].append(duration)
running_sum += duration
+ continue
+
if ("TestRunner: run finished:" in line) and (running_sum > 0):
- test_name = '*** TOTAL ALL TESTS (ms) ***'
+ test_name = ('*** TOTAL ALL TESTS [WAL] (ms) ***' if wal_enabled
+ else '*** TOTAL ALL TESTS (ms) ***')
if not test_name in timings:
timings[test_name] = []
timings[test_name].append(running_sum)
running_sum=0
+ continue
+
+ # Determine max from all reported totalWriteBytes
+ regex = r"Test .* totalWriteBytes=(\d+)"
+ matches = re.search(regex, line)
+ if matches:
+ max_write_bytes = max(max_write_bytes, int(matches.group(1)))
+ continue
for k in sorted(timings):
timings_ar = timings[k]
print "%s: %s avg: %s" % (k, timings_ar, sum(timings_ar) / float(len(timings_ar)) )
+
+ print "\nAdditional stats: "
+ print " max write_bytes: %d" % max_write_bytes
+
if __name__ == '__main__':
main()