Skip to content

Commit

Permalink
added bench/ directory to trunk, contains 2 benchmark suites.
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@826097 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
jchris committed Oct 16, 2009
1 parent 5123087 commit 2df3fab
Show file tree
Hide file tree
Showing 7 changed files with 412 additions and 4 deletions.
16 changes: 16 additions & 0 deletions bench/Makefile.am
@@ -0,0 +1,16 @@
## 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.

EXTRA_DIST = \
bench_lib.js \
runner.sh \
benches.js
241 changes: 241 additions & 0 deletions bench/bench_lib.js
@@ -0,0 +1,241 @@
// 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");
69 changes: 69 additions & 0 deletions bench/benchbulk.sh
@@ -0,0 +1,69 @@
#!/bin/sh -e
# 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.
#

# usage: time benchbulk.sh
# it takes about 30 seconds to run on my old MacBook with bulksize 1000

BULKSIZE=100
DOCSIZE=10
INSERTS=10
ROUNDS=10
DBURL="http://127.0.0.1:5984/benchbulk"
POSTURL="$DBURL/_bulk_docs"

function make_bulk_docs() {
ROW=0
SIZE=$(($1-1))
START=$2
BODYSIZE=$3

BODY=$(printf "%0${BODYSIZE}d")

echo '{"docs":['
while [ $ROW -lt $SIZE ]; do
printf '{"_id":"%020d", "body":"'$BODY'"},' $(($ROW + $START))
let ROW=ROW+1
done
printf '{"_id":"%020d", "body":"'$BODY'"}' $(($ROW + $START))
echo ']}'
}

echo "Making $INSERTS bulk inserts of $BULKSIZE docs each"

echo "Attempt to delete db at $DBURL"
curl -X DELETE $DBURL -w\\n

echo "Attempt to create db at $DBURL"
curl -X PUT $DBURL -w\\n

echo "Running $ROUNDS rounds of $INSERTS concurrent inserts to $POSTURL"
RUN=0
while [ $RUN -lt $ROUNDS ]; do

POSTS=0
while [ $POSTS -lt $INSERTS ]; do
STARTKEY=$[ POSTS * BULKSIZE + RUN * BULKSIZE * INSERTS ]
echo "startkey $STARTKEY bulksize $BULKSIZE"
DOCS=$(make_bulk_docs $BULKSIZE $STARTKEY $DOCSIZE)
# echo $DOCS
echo $DOCS | curl -T - -X POST $POSTURL -w%{http_code}\ %{time_total}\ sec\\n -o out.file 2> /dev/null &
let POSTS=POSTS+1
done

echo "waiting"
wait
let RUN=RUN+1
done

curl $DBURL -w\\n
62 changes: 62 additions & 0 deletions bench/benches.js
@@ -0,0 +1,62 @@
// 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;
};
1 change: 1 addition & 0 deletions bench/out.file
@@ -0,0 +1 @@
[{"id":"00000000000000000800","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000801","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000802","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000803","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000804","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000805","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000806","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000807","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000808","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000809","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000810","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000811","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000812","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000813","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000814","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000815","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000816","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000817","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000818","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000819","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000820","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000821","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000822","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000823","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000824","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000825","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000826","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000827","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000828","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000829","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000830","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000831","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000832","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000833","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000834","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000835","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000836","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000837","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000838","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000839","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000840","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000841","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000842","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000843","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000844","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000845","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000846","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000847","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000848","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000849","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000850","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000851","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000852","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000853","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000854","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000855","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000856","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000857","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000858","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000859","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000860","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000861","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000862","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000863","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000864","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000865","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000866","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000867","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000868","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000869","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000870","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000871","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000872","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000873","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000874","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000875","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000876","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000877","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000878","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000879","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000880","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000881","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000882","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000883","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000884","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000885","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000886","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000887","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000888","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000889","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000890","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000891","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000892","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000893","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000894","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000895","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000896","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000897","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000898","rev":"1-ca73793e047eb5e266cb27fd5952f89b"},{"id":"00000000000000000899","rev":"1-ca73793e047eb5e266cb27fd5952f89b"}]

0 comments on commit 2df3fab

Please sign in to comment.