diff options
author | Shaun Verch <shaun.verch@10gen.com> | 2013-02-25 17:53:14 -0800 |
---|---|---|
committer | Shaun Verch <shaun.verch@10gen.com> | 2013-04-11 14:09:55 -0700 |
commit | b7245d22bd7699400196e1d077bfdc3996b37bd9 (patch) | |
tree | bb998997bb66cc9fb97a560d7990a26417fd8a5e /jstests/perf | |
parent | 359b0b8c25e76b18bf6a366d9d6d9115f5a26fcc (diff) | |
download | mongo-b7245d22bd7699400196e1d077bfdc3996b37bd9.tar.gz |
SERVER-7760 Added parallel mapReduce test for v8
Diffstat (limited to 'jstests/perf')
-rw-r--r-- | jstests/perf/v8_mapreduce.js | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/jstests/perf/v8_mapreduce.js b/jstests/perf/v8_mapreduce.js new file mode 100644 index 00000000000..1c66f26d5b8 --- /dev/null +++ b/jstests/perf/v8_mapreduce.js @@ -0,0 +1,119 @@ +// Testing parallelism of mapReduce in V8 + +// Our server and client need to be running V8 and the host we are running on needs at least two +// cores. Update this if you are testing more than three threads in parallel. +if (/V8/.test(interpreterVersion()) && + db.runCommand({buildinfo:1}).javascriptEngine == "V8" && + db.hostInfo().system.numCores >= 2) { + + // function timeSingleThread + // Description: Gathers data about how long it takes to run a given job + // Args: job - job to run + // tid - thread id passed as an argument to the job, default 0 + // Returns: { threadStart : <time job started> , threadEnd : <time job completed> } + var timeSingleThread = function (job, tid) { + var tid = tid || 0; + var threadStart = new Date(); + job(tid); + return { "threadStart" : threadStart , "threadEnd" : new Date() }; + }; + + // function timeMultipleThreads + // Description: Gathers data about how long it takes to run a given job in multiple threads. + // Args: job - job to run in each thread + // nthreads - number of threads to spawn + // stagger - delay between each thread spawned in milliseconds + // Returns: Array with one entry for each thread of the form: + // [ { threadStart : <time elapsed before thread started work> , + // threadEnd : <time elapsed before thread completed work> } , + // ... + // ] + var timeMultipleThreads = function (job, nthreads, stagger) { + var i = 0; + var threads = []; + + for (i = 0; i < nthreads; ++i) { + threads[i] = new Thread(timeSingleThread, job, i); + } + + // Our "reference time" that all threads agree on + var referenceTime = new Date(); + + for (i = 0; i < nthreads; ++i) { + if (stagger && i > 0) { + sleep(stagger); + } + threads[i].start(); + } + + var threadTimes = []; + for (i = 0; i < nthreads; ++i) { + var returnData = threads[i].returnData(); + threadTimes[i] = {}; + threadTimes[i].threadStart = returnData.threadStart - referenceTime; + threadTimes[i].threadEnd = returnData.threadEnd - referenceTime; + } + + return threadTimes; + }; + + // Display and analysis helper functions + + var getLastCompletion = function (threadTimes) { + var lastCompletion = 0; + for (var i = 0; i < threadTimes.length; i++) { + lastCompletion = Math.max(lastCompletion, threadTimes[i].threadEnd); + } + return lastCompletion; + } + + // Functions we are performance testing + + db.v8_parallel_mr_src.drop(); + + for (j=0; j<100; j++) for (i=0; i<512; i++){ db.v8_parallel_mr_src.save({j:j, i:i})} + + db.getLastError(); + + var mrWorkFunction = function () { + + function verifyOutput(out) { + //printjson(out); + assert.eq(out.counts.input, 51200, "input count is wrong"); + assert.eq(out.counts.emit, 51200, "emit count is wrong"); + assert.gt(out.counts.reduce, 99, "reduce count is wrong"); + assert.eq(out.counts.output, 512, "output count is wrong"); + } + + function map() { + if (this.j % 2 == 0) { + emit(this.i, this.j*this.j); + } + else { + emit(this.i, this.j+this.j); + } + } + + function reduce(key, values) { + values_halved = values.map(function (value) { + return value / 2 + }); + values_halved_sum = Array.sum(values_halved); + return values_halved_sum; + } + + var out = db.v8_parallel_mr_src.mapReduce(map, reduce, { out : "v8_parallel_mr_out" }); + verifyOutput(out); + }; + + var oneMapReduce = getLastCompletion(timeMultipleThreads(mrWorkFunction, 1)); + var twoMapReduce = getLastCompletion(timeMultipleThreads(mrWorkFunction, 2)); + var threeMapReduce = getLastCompletion(timeMultipleThreads(mrWorkFunction, 3)); + + printjson("One map reduce job: " + oneMapReduce); + printjson("Two map reduce jobs: " + twoMapReduce); + printjson("Three map reduce jobs: " + threeMapReduce); + + assert(oneMapReduce * 1.75 > twoMapReduce); + assert(oneMapReduce * 2.5 > threeMapReduce); +} |