diff options
-rw-r--r-- | bench/bench_lib.js | 241 | ||||
-rw-r--r-- | bench/benches.js | 62 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/bench/Makefile.am (renamed from bench/Makefile.am) | 14 | ||||
-rw-r--r-- | test/bench/bench_marks.js | 103 | ||||
-rwxr-xr-x | test/bench/benchbulk.sh (renamed from bench/benchbulk.sh) | 0 | ||||
-rwxr-xr-x | test/bench/run.tpl (renamed from bench/runner.sh) | 18 |
8 files changed, 129 insertions, 312 deletions
diff --git a/bench/bench_lib.js b/bench/bench_lib.js deleted file mode 100644 index be7abcd9..00000000 --- a/bench/bench_lib.js +++ /dev/null @@ -1,241 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - -// some monkeypatches -var JSON = { - parse : function(string) { - return eval('('+string+')'); - }, - stringify : function(obj) { - return toJSON(obj||null); - } -}; - -RegExp.escape = function(text) { - if (!arguments.callee.sRE) { - var specials = [ - '/', '.', '*', '+', '?', '|', - '(', ')', '[', ']', '{', '}', '\\' - ]; - arguments.callee.sRE = new RegExp( - '(\\' + specials.join('|\\') + ')', 'g' - ); - } - return text.replace(arguments.callee.sRE, '\\$1'); -} - -// This is a JS wrapper for the curl function made available in couch_js.c, -// it should be used in other JavaScripts that would like to make HTTP calls. - -var HTTP = (function() { - function parseCurl(string) { - var parts = string.split(/\r\n\r\n/); - var body = parts.pop(); - var header = parts.pop(); - var headers = header.split(/\n/); - - var status = /HTTP\/1.\d (\d*)/.exec(header)[1]; - return { - responseText: body, - status: parseInt(status), - getResponseHeader: function(key) { - var keymatcher = new RegExp(RegExp.escape(key), "i"); - for (var i in headers) { - var h = headers[i]; - if (keymatcher.test(h)) { - var value = h.substr(key.length+2); - return value.replace(/^\s+|\s+$/g,""); - } - } - return ""; - } - } - }; - return { - GET : function(url, body, headers) { - var st, urx = url, hx = (headers || null); - st = gethttp(urx, hx); - return parseCurl(st); - }, - HEAD : function(url, body, headers) { - var st, urx = url, hx = (headers || null); - st = headhttp(urx, hx); - return parseCurl(st); - }, - DELETE : function(url, body, headers) { - var st, urx = url, hx = (headers || null); - st = delhttp(urx, hx); - return parseCurl(st); - }, - MOVE : function(url, body, headers) { - var st, urx = url, hx = (headers || null); - st = movehttp(urx, hx); - return parseCurl(st); - }, - COPY : function(url, body, headers) { - var st, urx = url, hx = (headers || null); - st = copyhttp(urx, hx); - return parseCurl(st); - }, - POST : function(url, body, headers) { - var st, urx = url, bx = (body || ""), hx = (headers || {}); - hx['Content-Type'] = hx['Content-Type'] || "application/json"; - st = posthttp(urx, bx, hx); - return parseCurl(st); - }, - PUT : function(url, body, headers) { - var st, urx = url, bx = (body || ""), hx = (headers || {}); - hx['Content-Type'] = hx['Content-Type'] || "application/json"; - st = puthttp(urx, bx, hx); - return parseCurl(st); - } - }; -})(); - -// Monkeypatches to CouchDB client for use of curl. - -CouchDB.host = (typeof window == 'undefined' || !window) ? "127.0.0.1:5984" : window; - -CouchDB.request = function(method, uri, options) { - var full_uri = "http://" + CouchDB.host + uri; - options = options || {}; - var response = HTTP[method](full_uri, options.body, options.headers); - return response; -} - - -function toJSON(val) { - if (typeof(val) == "undefined") { - throw {error:"bad_value", reason:"Cannot encode 'undefined' value as JSON"}; - } - var subs = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', - '\r': '\\r', '"' : '\\"', '\\': '\\\\'}; - if (typeof(val) == "xml") { // E4X support - val = val.toXMLString(); - } - return { - "Array": function(v) { - var buf = []; - for (var i = 0; i < v.length; i++) { - buf.push(toJSON(v[i])); - } - return "[" + buf.join(",") + "]"; - }, - "Boolean": function(v) { - return v.toString(); - }, - "Date": function(v) { - var f = function(n) { return n < 10 ? '0' + n : n } - return '"' + v.getUTCFullYear() + '-' + - f(v.getUTCMonth() + 1) + '-' + - f(v.getUTCDate()) + 'T' + - f(v.getUTCHours()) + ':' + - f(v.getUTCMinutes()) + ':' + - f(v.getUTCSeconds()) + 'Z"'; - }, - "Number": function(v) { - return isFinite(v) ? v.toString() : "null"; - }, - "Object": function(v) { - if (v === null) return "null"; - var buf = []; - for (var k in v) { - if (!v.hasOwnProperty(k) || typeof(k) !== "string" || v[k] === undefined) { - continue; - } - buf.push(toJSON(k, val) + ": " + toJSON(v[k])); - } - return "{" + buf.join(",") + "}"; - }, - "String": function(v) { - if (/["\\\x00-\x1f]/.test(v)) { - v = v.replace(/([\x00-\x1f\\"])/g, function(a, b) { - var c = subs[b]; - if (c) return c; - c = b.charCodeAt(); - return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); - }); - } - return '"' + v + '"'; - } - }[val != null ? val.constructor.name : "Object"](val); -} - - - -// *************** Test Framework Console Adapter ****************** // - -var p = print; -var numFailures = 0; - -function runAllBenchmarksConsole(dur, commit) { - var numBenches = 0; - p("Bench Duration: "+dur+"ms\n"); - for (var b in allBenches) { - p(b); - numBenches += 1; - var benchFun = allBenches[b]; - runBenchConsole(benchFun, dur, commit); - } - // p("Results: "+numFailures.toString() + " failures in "+numTests+" tests.") -}; - -function runBenchConsole(benchFun, duration, commit) { - var db = new CouchDB("bench_suite_db", {"X-Couch-Full-Commit":commit}); - try {db.createDb();} catch(e) {}; - - var acc = { - docs : 0, - }; - var loops = 0; - var start = new Date().getTime(); - try { - while(new Date().getTime() < start+duration) { - acc = benchFun(db, acc); - loops++; - } - p("OK"); - } catch(e) { - p("ERROR"); - p("Exception raised: "+e.toString()); - p("Backtrace: "+e.stack); - } - var duration = new Date().getTime() - start; - p(loops+" loops"); - p(acc.docs+" docs"); - p((acc.docs/(duration/1000))+" docs/sec\n"); -}; - - -// Use T to perform a test that returns false on failure and if the test fails, -// display the line that failed. -// Example: -// T(MyValue==1); -function T(arg1, arg2) { - if (!arg1) { - p("Assertion failed: "+(arg2 != null ? arg2 : arg1).toString()); - numFailures += 1 - } -} - -p("CouchDB Benchmarks"); -p("Host: "+CouchDB.host); - -try { - p("Version: "+CouchDB.getVersion()); - runAllBenchmarksConsole(10000,"false"); -} catch (e) { - p("error"); - p(e.toString()); -} - -p("Finished"); diff --git a/bench/benches.js b/bench/benches.js deleted file mode 100644 index 2e0a92db..00000000 --- a/bench/benches.js +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy of -// the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. - - -var allBenches = {}; - -allBenches.single_doc_insert = function(db, acc) { - db.save({"foo":"bar"}); - acc.docs++; - return acc; -}; - -allBenches.batch_ok_doc_insert = function(db, acc) { - db.save({"foo":"bar"}, {"batch":"ok"}); - acc.docs++; - return acc; -}; - -function makeDocs(n) { - docs = []; - for (var i=0; i < n; i++) { - docs.push({"foo":"bar"}); - }; - return docs; -}; - -allBenches.bulk_doc_100 = function(db, acc) { - var docs = makeDocs(100); - db.bulkSave(docs); - acc.docs += 100; - return acc; -}; - -allBenches.bulk_doc_1000 = function(db, acc) { - var docs = makeDocs(1000); - db.bulkSave(docs); - acc.docs += 1000; - return acc; -}; - -allBenches.bulk_doc_5000 = function(db, acc) { - var docs = makeDocs(5000); - db.bulkSave(docs); - acc.docs += 5000; - return acc; -}; - -allBenches.bulk_doc_10000 = function(db, acc) { - var docs = makeDocs(10000); - db.bulkSave(docs); - acc.docs += 10000; - return acc; -};
\ No newline at end of file diff --git a/configure.ac b/configure.ac index 24667bcc..86241edf 100644 --- a/configure.ac +++ b/configure.ac @@ -403,6 +403,7 @@ AC_CONFIG_FILES([src/etap/Makefile]) AC_CONFIG_FILES([src/ibrowse/Makefile]) AC_CONFIG_FILES([src/mochiweb/Makefile]) AC_CONFIG_FILES([test/Makefile]) +AC_CONFIG_FILES([test/bench/Makefile]) AC_CONFIG_FILES([test/etap/Makefile]) AC_CONFIG_FILES([test/etap/test_util.erl]) AC_CONFIG_FILES([test/javascript/Makefile]) diff --git a/test/Makefile.am b/test/Makefile.am index 4c4e54ea..45130a64 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -10,5 +10,5 @@ ## License for the specific language governing permissions and limitations under ## the License. -SUBDIRS = etap javascript view_server +SUBDIRS = bench etap javascript view_server diff --git a/bench/Makefile.am b/test/bench/Makefile.am index c98f4e01..ee3d03bd 100644 --- a/bench/Makefile.am +++ b/test/bench/Makefile.am @@ -10,7 +10,13 @@ ## License for the specific language governing permissions and limitations under ## the License. -EXTRA_DIST = \ - bench_lib.js \ - runner.sh \ - benches.js +EXTRA_DIST = benchbulk.sh benches.js + +noinst_SCRIPTS = run +CLEANFILES = run + +run: run.tpl + sed -e "s|%abs_top_srcdir%|$(abs_top_srcdir)|" \ + -e "s|%abs_top_builddir%|$(abs_top_builddir)|" \ + < $< > $@ + chmod +x $@ diff --git a/test/bench/bench_marks.js b/test/bench/bench_marks.js new file mode 100644 index 00000000..4025adbb --- /dev/null +++ b/test/bench/bench_marks.js @@ -0,0 +1,103 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +var NUM_DOCS = 2000; +var NUM_BATCHES = 20; + +var init = function() { + var db = new CouchDB("bench_mark_db", {"X-Couch-Full-Commit": "false"}); + db.deleteDb(); + db.createDb(); + return db; +}; + +var timeit = function(func) { + var startTime = (new Date()).getTime(); + func(); + return ((new Date()).getTime() - startTime) / 1000; +}; + +var report = function(name, rate) { + rate = Math.round(parseFloat(rate) * 100) / 100; + console.log("" + name + ": " + rate + " docs/second"); +}; + +var makeDocs = function(n) { + docs = []; + for (var i=0; i < n; i++) { + docs.push({"foo":"bar"}); + }; + return docs; +}; + +var couchTests = {}; + +couchTests.single_doc_insert = function() { + var db = init(); + var len = timeit(function() { + for(var i = 0; i < NUM_DOCS; i++) { + db.save({"foo": "bar"}); + } + }); + report("Single doc inserts", NUM_DOCS/len); +}; + +couchTests.batch_ok_doc_insert = function() { + var db = init(); + var len = timeit(function() { + for(var i = 0; i < NUM_DOCS; i++) { + db.save({"foo":"bar"}, {"batch":"ok"}); + } + }); + report("Single doc inserts with batch=ok", NUM_DOCS/len); +}; + +couchTests.bulk_doc_100 = function() { + var db = init(); + var len = timeit(function() { + for(var i = 0; i < NUM_BATCHES; i++) { + db.bulkSave(makeDocs(100)); + } + }); + report("Bulk docs - 100", (NUM_BATCHES*100)/len); +}; + +couchTests.bulk_doc_1000 = function() { + var db = init(); + var len = timeit(function() { + for(var i = 0; i < NUM_BATCHES; i++) { + db.bulkSave(makeDocs(1000)); + } + }); + report("Bulk docs - 1000", (NUM_BATCHES*1000)/len); +}; + + +couchTests.bulk_doc_5000 = function() { + var db = init(); + var len = timeit(function() { + for(var i = 0; i < NUM_BATCHES; i++) { + db.bulkSave(makeDocs(5000)); + } + }); + report("Bulk docs - 5000", (NUM_BATCHES*5000)/len); +}; + +couchTests.bulk_doc_10000 = function() { + var db = init(); + var len = timeit(function() { + for(var i = 0; i < NUM_BATCHES; i++) { + db.bulkSave(makeDocs(10000)); + } + }); + report("Bulk docs - 10000", (NUM_BATCHES*10000)/len); +}; diff --git a/bench/benchbulk.sh b/test/bench/benchbulk.sh index 22804c64..22804c64 100755 --- a/bench/benchbulk.sh +++ b/test/bench/benchbulk.sh diff --git a/bench/runner.sh b/test/bench/run.tpl index bdaffab5..9307863f 100755 --- a/bench/runner.sh +++ b/test/bench/run.tpl @@ -12,7 +12,17 @@ # License for the specific language governing permissions and limitations under # the License. -cat ../share/www/script/couch.js \ - benches.js \ - bench_lib.js \ - | ../src/couchdb/couchjs - +SRC_DIR=%abs_top_srcdir% +SCRIPT_DIR=$SRC_DIR/share/www/script +JS_TEST_DIR=$SRC_DIR/test/javascript +JS_BENCH_DIR=$SRC_DIR/test/bench + +COUCHJS=%abs_top_builddir%/src/couchdb/priv/couchjs + +cat $SCRIPT_DIR/json2.js \ + $SCRIPT_DIR/couch.js \ + $JS_TEST_DIR/couch_http.js \ + $JS_BENCH_DIR/bench_marks.js \ + $JS_TEST_DIR/cli_runner.js \ + | $COUCHJS - + |