diff options
author | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-29 23:27:37 +0000 |
---|---|---|
committer | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-29 23:27:37 +0000 |
commit | 81545760b52a29fbcc7a594b5b81fd1d7cdcf8ec (patch) | |
tree | 3b750fc0c9508b4eff5b9729e7e0613bb4328cb1 /tools/page_cycler/database | |
parent | 35f2094cd0ac27018aff2646445f44c3f9ee8d36 (diff) | |
download | chromium_src-81545760b52a29fbcc7a594b5b81fd1d7cdcf8ec.zip chromium_src-81545760b52a29fbcc7a594b5b81fd1d7cdcf8ec.tar.gz chromium_src-81545760b52a29fbcc7a594b5b81fd1d7cdcf8ec.tar.bz2 |
Adding the DB performance tests.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/465141
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35355 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/page_cycler/database')
17 files changed, 619 insertions, 0 deletions
diff --git a/tools/page_cycler/database/common.js b/tools/page_cycler/database/common.js new file mode 100644 index 0000000..75c50e4 --- /dev/null +++ b/tools/page_cycler/database/common.js @@ -0,0 +1,109 @@ +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview A collection of common functions used by all database + * performance tests. + */ + +var CANNOT_OPEN_DB = -1; +var SETUP_FAILED = -2; +var TEST_FAILED = -3; + +var TRANSACTIONS = 1000; // number of transactions; number of rows in the DB +var RANDOM_STRING_LENGTH = 20; // the length of the string on each row + +/** + * Generates a random string of upper-case letters of + * RANDOM_STRING_LENGTH length. + */ +function getRandomString() { + var s = ''; + for (var i = 0; i < RANDOM_STRING_LENGTH; i++) + s += String.fromCharCode(Math.floor(Math.random() * 26) + 64); + return s; +} + +/** + * Sets up and runs a performance test. + * @param {!Object} params An object which must have the following fields: + * dbName: The database name. + * readOnly: If true, transactions will be run using the readTransaction() + * method. Otherwise, transaction() will be used. + * insertRowsAtSetup: Determines if setting up the database should include + * inserting TRANSACTIONS rows in it. + * transactionCallback: The transaction callback that should be timed. This + * function will be run TRANSACTIONS times and must take a transaction + * object as its only parameter. + * customRunTransactions: A custom function for running and timing + * transactions. If this parameter is not null, runPerformanceTest() will + * ignore the txFnct parameter and will call customRunTransactions() as + * soon as the setup is complete. In this case, the user is responsible + * for running and timing the transactions. If not null, this parameter + * must be a function that takes a database object as its only parameter. + */ +function runPerformanceTest(params) { + var db = openTestDatabase(params.dbName); + if (!db) { + testComplete(CANNOT_OPEN_DB); + return; + } + + db.transaction( + function(tx) { + tx.executeSql('CREATE TABLE Test (ID INT, Foo TEXT)', [], + function(tx, data) {}, function(tx, error) {}); + tx.executeSql('DELETE FROM Test'); + if (params.insertRowsAtSetup) { + var randomString = getRandomString(); + for (var i = 0; i < TRANSACTIONS; i++) { + tx.executeSql('INSERT INTO Test VALUES (?, ?)', + [i, randomString]); + } + } + }, function(error) { + testComplete(SETUP_FAILED); + }, function() { + if (params.customRunTransactions) + params.customRunTransactions(db); + else + runTransactions(db, params.readOnly, params.transactionCallback); + }); +} + +/** + * Opens a database with the given name. + * @param {string} name The name of the database. + */ +function openTestDatabase(name) { + if (window.openDatabase) { + return window.openDatabase(name, '1.0', 'Test database.', + TRANSACTIONS * RANDOM_STRING_LENGTH); + } + + return null; +} + +/** + * Runs the given transaction TRANSACTIONS times. + * @param {!Object} db The database to run transactions on. + * @param {boolean} readOnly If true, all transactions will be run using the + * db.readTransaction() call. Otherwise, the transactions will be run + * using the db.transaction() call. + * @param {function(!Object)} The transaction callback. + */ +function runTransactions(db, readOnly, transactionCallback) { + var transactionsCompleted = 0; + var transactionFunction = readOnly ? db.readTransaction : db.transaction; + var startTime = Date.now(); + for (var i = 0; i < TRANSACTIONS; i++) { + transactionFunction.call(db, transactionCallback, + function(error) { + testComplete(TEST_FAILED); + }, function() { + if (++transactionsCompleted == TRANSACTIONS) + testComplete(Date.now() - startTime); + }); + } +} diff --git a/tools/page_cycler/database/delete-transactions/index.html b/tools/page_cycler/database/delete-transactions/index.html new file mode 100644 index 0000000..b5e5651 --- /dev/null +++ b/tools/page_cycler/database/delete-transactions/index.html @@ -0,0 +1,26 @@ +<!DOCTYPE HTML> +<html> +<title>Delete transactions</title> +<script src="../head.js"></script> +<script src="../common.js"></script> +<script> +var idCounter = 0; + +function transactionCallback(tx) { + tx.executeSql('DELETE FROM Test WHERE ID = ?', [idCounter++], + function(tx, data) {}, function(tx, error) {}); +} +</script> + +<body> +<script> + runPerformanceTest({ + dbName: "DeleteTransactions", + readOnly: false, + insertRowsAtSetup: true, + transactionCallback: transactionCallback, + customRunTransactions: null + }); +</script> +</body> +</html> diff --git a/tools/page_cycler/database/delete-transactions/start.html b/tools/page_cycler/database/delete-transactions/start.html new file mode 100644 index 0000000..596e60c --- /dev/null +++ b/tools/page_cycler/database/delete-transactions/start.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<h3>Note: You must have started chrome with <tt>--enable-file-cookies</tt> for +this test to work manually.</h3> +<script>document.cookie = "__pc_pages=delete-transactions; path=/";</script> +<script src="../start.js"></script> +</body> +</html> diff --git a/tools/page_cycler/database/head.js b/tools/page_cycler/database/head.js new file mode 100644 index 0000000..fedacec --- /dev/null +++ b/tools/page_cycler/database/head.js @@ -0,0 +1,120 @@ +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var totalTime; +var fudgeTime; +var elapsedTime; +var endTime; +var iterations; +var cycle; +var results = false; +var TIMEOUT = 15; + +/** + * Returns the value of the given property stored in the cookie. + * @param {string} name The property name. + * @return {string} The value of the given property, or empty string + * if the property was not found. + */ +function getPropertyValue(name) { + var cookies = document.cookie.split('; '); + for (var i = 0; i < cookies.length; ++i) { + var t = cookies[i].split('='); + if ((t[0] == name) && t[1]) + return t[1]; + } + return ''; +} + +/** + * Returns the value of the '__pc_timings' property. + * @return {string} The list of all timings we got so far. + */ +function getTimings() { + return getPropertyValue('__pc_timings'); +} + +/** + * Sets the value of the '__pc_timings' property in the cookie. + * @param {string} timings A comma-separated list of timings. + */ +function setTimings(timings) { + document.cookie = '__pc_timings=' + timings + '; path=/'; +} + +/** + * Starts the next test cycle or redirects the browser to the results page. + */ +function nextCycleOrResults() { + // Call GC twice to cleanup JS heap before starting a new test. + if (window.gc) { + window.gc(); + window.gc(); + } + + var tLag = Date.now() - endTime - TIMEOUT; + if (tLag > 0) + fudgeTime += tLag; + + var doc; + if (cycle == iterations) { + document.cookie = '__pc_done=1; path=/'; + doc = '../../common/report.html'; + } else { + doc = 'index.html'; + } + + var timings = elapsedTime; + var oldTimings = getTimings(); + if (oldTimings != '') + timings = oldTimings + ',' + timings; + setTimings(timings); + + var url = doc + '?n=' + iterations + '&i=' + cycle + + '&td=' + totalTime + '&tf=' + fudgeTime; + document.location.href = url; +} + +/** + * Computes various running times and updates the stats reported at the end. + * @param {!number} cycleTime The running time of the test cycle. + */ +function testComplete(cycleTime) { + if (results) + return; + + var oldTotalTime = 0; + var cycleEndTime = Date.now(); + var cycleFudgeTime = 0; + + var s = document.location.search; + if (s) { + var params = s.substring(1).split('&'); + for (var i = 0; i < params.length; i++) { + var f = params[i].split('='); + switch (f[0]) { + case 'skip': + return; // No calculation, just viewing + case 'n': + iterations = f[1]; + break; + case 'i': + cycle = f[1] - 0 + 1; + break; + case 'td': + oldTotalTime = f[1] - 0; + break; + case 'tf': + cycleFudgeTime = f[1] - 0; + break; + } + } + } + elapsedTime = cycleTime; + totalTime = oldTotalTime + elapsedTime; + endTime = cycleEndTime; + fudgeTime = cycleFudgeTime; + + setTimeout(nextCycleOrResults, TIMEOUT); +} diff --git a/tools/page_cycler/database/insert-transactions/index.html b/tools/page_cycler/database/insert-transactions/index.html new file mode 100644 index 0000000..f17b977 --- /dev/null +++ b/tools/page_cycler/database/insert-transactions/index.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<title>Insert transactions</title> +<script src="../head.js"></script> +<script src="../common.js"></script> +<script> +var randomString = getRandomString(); +var idCounter = 0; + +function transactionCallback(tx) { + tx.executeSql('INSERT INTO Test VALUES (?, ?)', + [idCounter++, randomString], + function(tx, data) {}, function(tx, error) {}); +} +</script> + +<body> +<script> + runPerformanceTest({ + dbName: "InsertTransactions", + readOnly: false, + insertRowsAtSetup: false, + transactionCallback: transactionCallback, + customRunTransactions: null + }); +</script> +</body> +</html> diff --git a/tools/page_cycler/database/insert-transactions/start.html b/tools/page_cycler/database/insert-transactions/start.html new file mode 100644 index 0000000..f8538de --- /dev/null +++ b/tools/page_cycler/database/insert-transactions/start.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<h3>Note: You must have started chrome with <tt>--enable-file-cookies</tt> for +this test to work manually.</h3> +<script>document.cookie = "__pc_pages=insert-transactions; path=/";</script> +<script src="../start.js"></script> +</body> +</html> diff --git a/tools/page_cycler/database/pseudo-random-transactions/index.html b/tools/page_cycler/database/pseudo-random-transactions/index.html new file mode 100644 index 0000000..3732bce --- /dev/null +++ b/tools/page_cycler/database/pseudo-random-transactions/index.html @@ -0,0 +1,103 @@ +<!DOCTYPE HTML> +<html> +<title>Pseudo-random transactions</title> +<script src="../head.js"></script> +<script src="../common.js"></script> +<script> +var SELECT_STATEMENT_IN_READ_TRANSACTION = 0; +var SELECT_STATEMENT_IN_TRANSACTION = 1; +var INSERT_STATEMENT = 2; +var UPDATE_STATEMENT = 3; +var DELETE_STATEMENT = 4; +var STATEMENTS = + [2, 0, 4, 2, 2, 2, 2, 2, 1, 4, 1, 1, 0, 2, 0, 0, 2, 1, 2, 0, + 4, 4, 2, 3, 3, 4, 3, 1, 3, 3, 2, 4, 3, 3, 2, 3, 1, 1, 4, 2, + 4, 1, 4, 2, 3, 0, 4, 2, 4, 0, 4, 3, 3, 2, 0, 2, 1, 4, 4, 4, + 4, 2, 3, 2, 0, 3, 3, 0, 4, 4, 4, 2, 3, 1, 4, 2, 4, 2, 3, 0, + 2, 4, 0, 4, 2, 2, 4, 0, 3, 2, 3, 2, 3, 2, 0, 0, 4, 0, 2, 0]; + +var transactionsCompleted = 0; +var startTime = 0; + +function statementSuccessCallback(tx, data) {} +function statementErrorCallback(tx, error) {} + +function transactionSuccessCallback() { + if (++transactionsCompleted == TRANSACTIONS) + testComplete(Date.now() - startTime); +} + +function transactionErrorCallback(error) { + testComplete(TEST_FAILED); +} + +function customRunTransactions(db) { + var selectIDCounter = 0; + var insertIDCounter = 0; + var updateIDCounter = 0; + var deleteIDCounter = 0; + var randomString = getRandomString(); + var randomStringForUpdates = getRandomString(); + startTime = Date.now(); + for (var i = 0; i < TRANSACTIONS; i++) { + switch (STATEMENTS[i % STATEMENTS.length]) { + case SELECT_STATEMENT_IN_READ_TRANSACTION: + db.readTransaction( + function(tx) { + tx.executeSql('SELECT * FROM Test WHERE ID = ?', + [selectIDCounter++], + statementSuccessCallback, statementErrorCallback); + }, transactionErrorCallback, transactionSuccessCallback); + break; + case SELECT_STATEMENT_IN_TRANSACTION: + db.transaction( + function(tx) { + tx.executeSql('SELECT * FROM Test WHERE ID = ?', + [selectIDCounter++], + statementSuccessCallback, statementErrorCallback); + }, transactionErrorCallback, transactionSuccessCallback); + break; + case INSERT_STATEMENT: + db.transaction( + function(tx) { + tx.executeSql('INSERT INTO Test VALUES (?, ?)', + [insertIDCounter++, randomString], + statementSuccessCallback, statementErrorCallback); + }, transactionErrorCallback, transactionSuccessCallback); + break; + case UPDATE_STATEMENT: + db.transaction( + function(tx) { + tx.executeSql('UPDATE Test SET Foo = ? WHERE ID = ?', + [randomStringForUpdates, updateIDCounter++], + statementSuccessCallback, statementErrorCallback); + }, transactionErrorCallback, transactionSuccessCallback); + break; + case DELETE_STATEMENT: + db.transaction( + function(tx) { + tx.executeSql('DELETE FROM Test WHERE ID = ?', + [deleteIDCounter++], + statementSuccessCallback, statementErrorCallback); + }, transactionErrorCallback, transactionSuccessCallback); + break; + default: + testComplete(TEST_FAILED); + return; + } + } +} +</script> + +<body> +<script> + runPerformanceTest({ + dbName: "PseudoRandomTransactions", + readOnly: false, + insertRowsAtSetup: true, + transactionCallback: null, + customRunTransactions: customRunTransactions + }); +</script> +</body> +</html> diff --git a/tools/page_cycler/database/pseudo-random-transactions/start.html b/tools/page_cycler/database/pseudo-random-transactions/start.html new file mode 100644 index 0000000..6278291 --- /dev/null +++ b/tools/page_cycler/database/pseudo-random-transactions/start.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<h3>Note: You must have started chrome with <tt>--enable-file-cookies</tt> for +this test to work manually.</h3> +<script>document.cookie = "__pc_pages=pseudo-random-transactions; path=/";</script> +<script src="../start.js"></script> +</body> +</html> diff --git a/tools/page_cycler/database/select-readtransactions-read-results/index.html b/tools/page_cycler/database/select-readtransactions-read-results/index.html new file mode 100644 index 0000000..40a2d87 --- /dev/null +++ b/tools/page_cycler/database/select-readtransactions-read-results/index.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<title>Select read-transactions (store results in JS variables)</title> +<script src="../head.js"></script> +<script src="../common.js"></script> +<script> +var idCounter = 0; +var resultId = 0; +var resultString = ''; + +function transactionCallback(tx) { + tx.executeSql('SELECT * FROM Test WHERE ID = ?', [idCounter++], + function(tx, data) { + for (var i = 0; i < data.rows.length; i++) { + resultId = data.rows.item(i).ID; + resultString = data.rows.item(i).Foo; + } + }, function(tx, error) {}); +} +</script> + +<body> +<script> + runPerformanceTest({ + dbName: "SelectReadTransactionsReadResults", + readOnly: true, + insertRowsAtSetup: true, + transactionCallback: transactionCallback, + customRunTransactions: null + }); +</script> +</body> +</html> diff --git a/tools/page_cycler/database/select-readtransactions-read-results/start.html b/tools/page_cycler/database/select-readtransactions-read-results/start.html new file mode 100644 index 0000000..bbb0aef --- /dev/null +++ b/tools/page_cycler/database/select-readtransactions-read-results/start.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<h3>Note: You must have started chrome with <tt>--enable-file-cookies</tt> for +this test to work manually.</h3> +<script>document.cookie = "__pc_pages=select-readtransactions-read-results; path=/";</script> +<script src="../start.js"></script> +</body> +</html> diff --git a/tools/page_cycler/database/select-readtransactions/index.html b/tools/page_cycler/database/select-readtransactions/index.html new file mode 100644 index 0000000..e923bc2 --- /dev/null +++ b/tools/page_cycler/database/select-readtransactions/index.html @@ -0,0 +1,26 @@ +<!DOCTYPE HTML> +<html> +<title>Select read-transactions</title> +<script src="../head.js"></script> +<script src="../common.js"></script> +<script> +var idCounter = 0; + +function transactionCallback(tx) { + tx.executeSql('SELECT * FROM Test WHERE ID = ?', [idCounter++], + function(tx, data) {}, function(tx, error) {}); +} +</script> + +<body> +<script> + runPerformanceTest({ + dbName: "SelectReadTransactions", + readOnly: true, + insertRowsAtSetup: true, + transactionCallback: transactionCallback, + customRunTransactions: null + }); +</script> +</body> +</html> diff --git a/tools/page_cycler/database/select-readtransactions/start.html b/tools/page_cycler/database/select-readtransactions/start.html new file mode 100644 index 0000000..6833f1b --- /dev/null +++ b/tools/page_cycler/database/select-readtransactions/start.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<h3>Note: You must have started chrome with <tt>--enable-file-cookies</tt> for +this test to work manually.</h3> +<script>document.cookie = "__pc_pages=select-readtransactions; path=/";</script> +<script src="../start.js"></script> +</body> +</html> diff --git a/tools/page_cycler/database/select-transactions/index.html b/tools/page_cycler/database/select-transactions/index.html new file mode 100644 index 0000000..bfd0b39 --- /dev/null +++ b/tools/page_cycler/database/select-transactions/index.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<html> +<title>Select transactions</title> +<script src="../head.js"></script> +<script src="../common.js"></script> +<script> +var idCounter = 0; + +function transactionCallback(tx) { + tx.executeSql('SELECT * FROM Test WHERE ID = ?', [idCounter++], + function(tx, data) {}, function(tx, error) {}); +} +</script> + +<body> +<script> + runPerformanceTest({ + dbName: "SelectTransactions", + readOnly: false, + insertRowsAtSetup: true, + transactionCallback: transactionCallback, + customRunTransactions: null + });</script> +</body> +</html> diff --git a/tools/page_cycler/database/select-transactions/start.html b/tools/page_cycler/database/select-transactions/start.html new file mode 100644 index 0000000..ce9d2e9 --- /dev/null +++ b/tools/page_cycler/database/select-transactions/start.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<h3>Note: You must have started chrome with <tt>--enable-file-cookies</tt> for +this test to work manually.</h3> +<script>document.cookie = "__pc_pages=select-transactions; path=/";</script> +<script src="../start.js"></script> +</body> +</html> diff --git a/tools/page_cycler/database/start.js b/tools/page_cycler/database/start.js new file mode 100644 index 0000000..c3da326 --- /dev/null +++ b/tools/page_cycler/database/start.js @@ -0,0 +1,58 @@ +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +document.title = 'page cycler'; + +document.cookie = '__pc_done=0; path=/'; +document.cookie = '__pc_timings=; path=/'; + +var options = location.search.substring(1).split('&'); + +function getOption(name) { + var r = new RegExp('^' + name + '='); + for (var i = 0; i < options.length; i++) { + if (options[i].match(r)) { + return options[i].substring(name.length + 1); + } + } + return null; +} + +function start() { + var iterations = document.getElementById('iterations').value; + window.resizeTo(800, 800); + var url = 'index.html?n=' + iterations + '&i=0&td=0'; + window.location = url; +} + +function renderForm() { + var form = document.createElement('form'); + form.onsubmit = function(e) { + start(); + e.preventDefault(); + }; + + var label = document.createTextNode('Iterations: '); + form.appendChild(label); + + var input = document.createElement('input'); + input.id = 'iterations'; + input.type = 'number'; + var iterations = getOption('iterations'); + input.value = iterations ? iterations : '5'; + form.appendChild(input); + + input = document.createElement('input'); + input.type = 'submit'; + input.value = 'Start'; + form.appendChild(input); + + document.body.appendChild(form); +} + +renderForm(); + +// should we start automatically? +if (location.search.match('auto=1')) + start(); diff --git a/tools/page_cycler/database/update-transactions/index.html b/tools/page_cycler/database/update-transactions/index.html new file mode 100644 index 0000000..75d3c57 --- /dev/null +++ b/tools/page_cycler/database/update-transactions/index.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<title>Update transactions</title> +<script src="../head.js"></script> +<script src="../common.js"></script> +<script> +var randomString = getRandomString(); +var idCounter = 0; + +function transactionCallback(tx) { + tx.executeSql('UPDATE Test SET Foo = ? WHERE ID = ?', + [randomString, idCounter++], + function(tx, data) {}, function(tx, error) {}); +} +</script> + +<body> +<script> + runPerformanceTest({ + dbName: "UpdateTransactions", + readOnly: false, + insertRowsAtSetup: true, + transactionCallback: transactionCallback, + customRunTransactions: null + }); +</script> +</body> +</html> diff --git a/tools/page_cycler/database/update-transactions/start.html b/tools/page_cycler/database/update-transactions/start.html new file mode 100644 index 0000000..2c2e2a0 --- /dev/null +++ b/tools/page_cycler/database/update-transactions/start.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<h3>Note: You must have started chrome with <tt>--enable-file-cookies</tt> for +this test to work manually.</h3> +<script>document.cookie = "__pc_pages=update-transactions; path=/";</script> +<script src="../start.js"></script> +</body> +</html> |