Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

simple js benchmakring harness

  • Loading branch information...
commit 3db3cb13dc1c522db8b59745d6c74b0967f1611c 1 parent 57c2cf9
Eliot authored September 14, 2010
2  SConstruct
@@ -453,7 +453,7 @@ serverOnlyFiles += [ "db/dbcommands.cpp" , "db/dbcommands_admin.cpp" ]
453 453
 coreServerFiles += Glob( "db/stats/*.cpp" )
454 454
 serverOnlyFiles += [ "db/driverHelpers.cpp" ]
455 455
 
456  
-scriptingFiles = [ "scripting/engine.cpp" , "scripting/utils.cpp" ]
  456
+scriptingFiles = [ "scripting/engine.cpp" , "scripting/utils.cpp" , "scripting/bench.cpp" ]
457 457
 
458 458
 if usesm:
459 459
     scriptingFiles += [ "scripting/engine_spidermonkey.cpp" ]
173  scripting/bench.cpp
... ...
@@ -0,0 +1,173 @@
  1
+/** @file bench.cpp */
  2
+
  3
+/*
  4
+ *    Copyright (C) 2010 10gen Inc.
  5
+ *
  6
+ *    This program is free software: you can redistribute it and/or  modify
  7
+ *    it under the terms of the GNU Affero General Public License, version 3,
  8
+ *    as published by the Free Software Foundation.
  9
+ *
  10
+ *    This program is distributed in the hope that it will be useful,
  11
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13
+ *    GNU Affero General Public License for more details.
  14
+ *
  15
+ *    You should have received a copy of the GNU Affero General Public License
  16
+ *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17
+ */
  18
+
  19
+#include "pch.h"
  20
+#include "engine.h"
  21
+#include "../util/md5.hpp"
  22
+#include "../util/version.h"
  23
+#include "../client/dbclient.h"
  24
+#include "../client/connpool.h"
  25
+// ---------------------------------
  26
+// ---- benchmarking system --------
  27
+// ---------------------------------
  28
+
  29
+
  30
+namespace mongo {
  31
+
  32
+
  33
+    /**
  34
+     * benchQuery( "foo" , { _id : 1 } )
  35
+     */
  36
+    BSONObj benchQuery( const BSONObj& args ){
  37
+        return BSONObj();
  38
+    }
  39
+
  40
+    struct BenchRunConfig {
  41
+        BenchRunConfig(){
  42
+            host = "localhost";
  43
+            db = "test";
  44
+            
  45
+            parallel = 1;
  46
+            seconds = 1;
  47
+
  48
+            active = true;
  49
+            threadsReady = 0;
  50
+            error = false;
  51
+        }
  52
+        
  53
+        string host;
  54
+        string db;
  55
+        
  56
+        unsigned parallel;
  57
+        int seconds;
  58
+
  59
+        BSONObj ops;
  60
+
  61
+        bool active; // true at starts, gets set to false when should stop
  62
+        AtomicUInt threadsReady;
  63
+
  64
+        bool error;
  65
+    };
  66
+    
  67
+    void runBench( BenchRunConfig * config ){
  68
+        ScopedDbConnection conn( config->host );
  69
+        config->threadsReady++;        
  70
+        
  71
+        while ( config->active ){
  72
+            BSONObjIterator i( config->ops );
  73
+            while ( i.more() ){
  74
+                BSONElement e = i.next();
  75
+                string ns = e["ns"].String();
  76
+                string op = e["op"].String();
  77
+                
  78
+                if ( op == "findOne" ) {
  79
+                    conn->findOne( ns , e["query"].Obj() );
  80
+                }
  81
+                else {
  82
+                    log() << "don't understand op: " << op << endl;
  83
+                    config->error = true;
  84
+                    return;
  85
+                }
  86
+
  87
+            }
  88
+        }
  89
+
  90
+        conn.done();
  91
+    }
  92
+    
  93
+    /**
  94
+     * benchRun( { ops : [] , host : XXX , db : XXXX , parallel : 5 , seconds : 5 }
  95
+     */
  96
+    BSONObj benchRun( const BSONObj& argsFake ){
  97
+        assert( argsFake.firstElement().isABSONObj() );
  98
+        BSONObj args = argsFake.firstElement().Obj();
  99
+
  100
+        // setup
  101
+
  102
+        BenchRunConfig config;
  103
+        
  104
+        if ( args["host"].type() == String )
  105
+            config.host = args["host"].String();
  106
+        if ( args["db"].type() == String )
  107
+            config.db = args["db"].String();
  108
+
  109
+        if ( args["parallel"].isNumber() )
  110
+            config.parallel = args["parallel"].numberInt();
  111
+        if ( args["seconds"].isNumber() )
  112
+            config.seconds = args["seconds"].numberInt();
  113
+
  114
+
  115
+        config.ops = args["ops"].Obj();
  116
+
  117
+        // execute
  118
+
  119
+        ScopedDbConnection conn( config.host );
  120
+
  121
+        //    start threads
  122
+        vector<boost::thread*> all;
  123
+        for ( unsigned i=0; i<config.parallel; i++ )
  124
+            all.push_back( new boost::thread( boost::bind( runBench , &config ) ) );
  125
+        
  126
+        //    give them time to init
  127
+        while ( config.threadsReady < config.parallel )
  128
+            sleepmillis( 1 );
  129
+
  130
+        BSONObj before;
  131
+        conn->simpleCommand( "admin" , &before , "serverStatus" );
  132
+        
  133
+        sleepsecs( config.seconds );
  134
+
  135
+        BSONObj after;
  136
+        conn->simpleCommand( "admin" , &after , "serverStatus" );
  137
+        
  138
+        conn.done();
  139
+
  140
+        config.active = false;
  141
+        
  142
+        for ( unsigned i=0; i<all.size(); i++ )
  143
+            all[i]->join();
  144
+        
  145
+        if ( config.error )
  146
+            return BSON( "err" << 1 );
  147
+        
  148
+        // compute actual ops/sec
  149
+        
  150
+        before = before["opcounters"].Obj();
  151
+        after = after["opcounters"].Obj();
  152
+        
  153
+        BSONObjBuilder buf;
  154
+        buf.append( "note" , "values per second" );
  155
+
  156
+        {
  157
+            BSONObjIterator i( after );
  158
+            while ( i.more() ){
  159
+                BSONElement e = i.next();
  160
+                double x = e.number();
  161
+                x = x - before[e.fieldName()].number();
  162
+                buf.append( e.fieldName() , x / config.seconds );
  163
+            }
  164
+        }
  165
+        BSONObj zoo = buf.obj();
  166
+        return BSON( "" << zoo );
  167
+    }
  168
+
  169
+    void installBenchmarkSystem( Scope& scope ){
  170
+        scope.injectNative( "benchRun" , benchRun );
  171
+    }
  172
+
  173
+}
9  scripting/utils.cpp
@@ -23,6 +23,8 @@
23 23
 
24 24
 namespace mongo {
25 25
 
  26
+    void installBenchmarkSystem( Scope& scope );
  27
+
26 28
     BSONObj jsmd5( const BSONObj &a ){
27 29
         uassert( 10261 ,  "js md5 needs a string" , a.firstElement().type() == String );
28 30
         const char * s = a.firstElement().valuestrsafe();
@@ -43,9 +45,16 @@ namespace mongo {
43 45
         return BSONObj();
44 46
     }
45 47
 
  48
+
  49
+    // ---------------------------------
  50
+    // ---- installer           --------
  51
+    // ---------------------------------
  52
+
46 53
     void installGlobalUtils( Scope& scope ){
47 54
         scope.injectNative( "hex_md5" , jsmd5 );
48 55
         scope.injectNative( "version" , JSVersion );
  56
+
  57
+        installBenchmarkSystem( scope );
49 58
     }
50 59
 
51 60
 }

0 notes on commit 3db3cb1

Please sign in to comment.
Something went wrong with that request. Please try again.