Browse Source

Merge branch 'master' into fortune

Patrick Falls 12 years ago
parent
commit
95f3376b0e

+ 1 - 1
benchmarker.py

@@ -306,7 +306,7 @@ class Benchmarker:
         continue
       
       # If the test does not contain an implementation of the current test-type, skip it
-      if not test.contains_type(self.type):
+      if self.type != 'all' and not test.contains_type(self.type):
         continue
       
       print textwrap.dedent("""

+ 11 - 7
dancer/app.pl

@@ -3,11 +3,13 @@ use strict;
 use warnings;
 
 use Dancer ':syntax';
-use Dancer::Plugin::Database;
+use DBI;
+
 set serializer => 'JSON';
 
-#my $dbh = database({ driver => 'mysql', database => 'test' });
-my $dbh = database({ driver => 'mysql', host => 'localhost', database => 'hello_world', username => 'benchmarkdbuser', password => 'benchmarkdbpass' });
+my $dsn = "dbi:mysql:database=hello_world;host=localhost;port=3306";
+my $dbh = DBI->connect( $dsn, 'benchmarkdbuser', 'benchmarkdbpass', {} );
+my $sth = $dbh->prepare("SELECT * FROM World where id = ?");
 
 get '/json' => sub {
     { message => 'Hello, World!' }
@@ -16,13 +18,15 @@ get '/json' => sub {
 get '/db' => sub {
     my $queries = params->{queries} || 1;
     my @response;
-    for( 1 .. $queries ) {
+    for ( 1 .. $queries ) {
         my $id = int rand 10000 + 1;
-        if ( my $row = $dbh->quick_select( 'world', { id => $id } ) ) {
-            push @response, { id => $id, randomNumber => $row->{randomNumber} };
+        $sth->execute($id);
+        if ( my $row = $sth->fetchrow_hashref ) {
+            push @response,
+              { id => $id, randomNumber => $row->{randomNumber} };
         }
     }
-    { \@response }
+    return \@response;
 };
 
 Dancer->dance;

+ 1 - 2
dancer/benchmark_config

@@ -15,5 +15,4 @@
       "sort": 77
     }
   }]
-}
-
+}

+ 2 - 2
dancer/nginx.conf

@@ -1,4 +1,4 @@
-user pfalls;
+user USR;
 
 worker_processes 2;
 
@@ -16,7 +16,7 @@ http {
   tcp_nodelay      on;
 
   upstream backendurl {
-    server unix:/home/pfalls/FrameworkBenchmarks/dancer/frameworks-benchmark.sock;
+    server unix:/home/ubuntu/FrameworkBenchmarks/dancer/frameworks-benchmark.sock;
   }
 
   server {

+ 1 - 1
dancer/setup.py

@@ -24,7 +24,7 @@ def stop():
     p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
     out, err = p.communicate()
     for line in out.splitlines():
-      if 'plackup' in line:
+      if 'starman' in line:
         pid = int(line.split(None, 2)[1])
         os.kill(pid, 9)
     return 0

+ 2 - 1
express/benchmark_config

@@ -18,8 +18,9 @@
       "setup_file": "setup",
       "db_url": "/sequelize",
       "query_url": "/sequelize?queries=",
+      "fortune_url": "/fortune",
       "port": 8080,
       "sort": 6
     }
   }]
-}
+}

+ 2 - 2
go/README.md

@@ -7,10 +7,10 @@ This is the go portion of a [benchmarking test suite](../) comparing a variety o
 
 ## Versions
 
-* [Go 1.0.3](http://golang.org/)
+* [Go 1.1beta2](http://golang.org/)
 
 ## Test URLs
 
 ### JSON Encoding Test
 
-http://localhost:8080/json
+http://localhost:8080/json

+ 58 - 40
go/src/hello/hello.go

@@ -4,13 +4,13 @@ import (
 	"database/sql"
 	"encoding/json"
 	_ "github.com/go-sql-driver/mysql"
+	"html/template"
 	"log"
 	"math/rand"
 	"net/http"
 	"runtime"
-	"strconv"
-        "html/template"
 	"sort"
+	"strconv"
 )
 
 type MessageStruct struct {
@@ -23,33 +23,48 @@ type World struct {
 }
 
 type Fortune struct {
-	Id           uint16 `json:"id"`
-	Message      string `json:"message"`
+	Id      uint16 `json:"id"`
+	Message string `json:"message"`
 }
 
 const (
 	DB_CONN_STR           = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world?charset=utf8"
-	DB_SELECT_SQL         = "SELECT id, randomNumber FROM World where id = ?;"
+	DB_SELECT_SQL         = "SELECT id, randomNumber FROM World where id = ?"
 	DB_FORTUNE_SELECT_SQL = "SELECT id, message FROM Fortune;"
 	DB_ROWS               = 10000
+	MAX_CONN              = 80
 )
 
 var (
-	db    *sql.DB
-	query *sql.Stmt
+	stmts        = make(chan *sql.Stmt, MAX_CONN)
+	fortuneStmts = make(chan *sql.Stmt, MAX_CONN)
+	tmpl         = template.Must(template.ParseFiles("templates/layout.html", "templates/fortune.html"))
 )
 
+func init() {
+	//setup DB connection pool to work around Go issue #4805: https://code.google.com/p/go/issues/detail?id=4805&q=sql.db&colspec=ID%20Status%20Stars%20Priority%20Owner%20Reporter%20Summary
+	for i := 0; i < MAX_CONN; i++ {
+		db, err := sql.Open("mysql", DB_CONN_STR)
+		if err != nil {
+			log.Fatalf("Error opening database: %s", err)
+		}
+		stmt, err := db.Prepare(DB_SELECT_SQL)
+		if err != nil {
+			log.Fatal(err)
+		}
+		stmts <- stmt
+		fortuneStmt, err := db.Prepare(DB_FORTUNE_SELECT_SQL)
+		if err != nil {
+			log.Fatal(err)
+		}
+		fortuneStmts <- fortuneStmt
+	}
+}
+
 func main() {
 	runtime.GOMAXPROCS(runtime.NumCPU())
-	var err error
-	if db, err = sql.Open("mysql", DB_CONN_STR); err != nil {
-		log.Fatalf("Error opening database: %s", err)
-	}
-	if query, err = db.Prepare(DB_SELECT_SQL); err != nil {
-		log.Fatalf("Error preparing statement: %s", err)
-	}
-	http.HandleFunc("/json", jsonHandler)
 	http.HandleFunc("/db", dbHandler)
+	http.HandleFunc("/json", jsonHandler)
 	http.HandleFunc("/fortune", fortuneHandler)
 	http.ListenAndServe(":8080", nil)
 }
@@ -62,51 +77,54 @@ func jsonHandler(w http.ResponseWriter, r *http.Request) {
 }
 
 func dbHandler(w http.ResponseWriter, r *http.Request) {
-  	qnum := 1
-	if qnumStr := r.URL.Query().Get("queries"); len(qnumStr) != 0 {
-		qnum, _ = strconv.Atoi(qnumStr)
+	n := 1
+	if nStr := r.URL.Query().Get("queries"); len(nStr) != 0 {
+		n, _ = strconv.Atoi(nStr)
 	}
-	ww := make([]World, qnum)
-	for i := 0; i < qnum; i++ {
-		query.QueryRow(rand.Intn(DB_ROWS)+1).Scan(&ww[i].Id, &ww[i].RandomNumber)
+	ww := make([]World, n)
+	stmt := <-stmts //wait for a connection
+	for i := 0; i < n; i++ {
+		stmt.QueryRow(rand.Intn(DB_ROWS)+1).Scan(&ww[i].Id, &ww[i].RandomNumber)
 	}
-	w.Header().Set("Content-Type", "application/javascript")
+	stmts <- stmt //get a connection
 	j, _ := json.Marshal(ww)
+	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
 	w.Write(j)
 }
 
 func fortuneHandler(w http.ResponseWriter, r *http.Request) {
-	// the Fortune table contains 12 rows, and we'll add another Fortune ourselves
-	fortunes := make([]Fortune, 13)
-  
-	// Execute the query
-	rows, err := db.Query(DB_FORTUNE_SELECT_SQL)
+	fortunes := make([]*Fortune, 0, 16)
+	stmt := <-fortuneStmts    //wait for a connection
+	rows, err := stmt.Query() //Execute the query
 	if err != nil {
 		log.Fatalf("Error preparing statement: %s", err)
 	}
-  
 	i := 0
-	// Fetch rows
-	for rows.Next() {
-		// get RawBytes from data
-		err = rows.Scan(&fortunes[i].Id, &fortunes[i].Message)
-		if err != nil {
-			panic(err.Error())
+	var fortune *Fortune
+	for rows.Next() { //Fetch rows
+		fortune = new(Fortune)
+		if err = rows.Scan(&fortune.Id, &fortune.Message); err != nil {
+			panic(err)
 		}
+		fortunes = append(fortunes, fortune)
 		i++
 	}
-        fortunes[i].Message = "Additional fortune added at request time."
-	
-  	sort.Sort(ByMessage{fortunes})
-	var tmpl = template.Must(template.ParseFiles("templates/layout.html", "templates/fortune.html"))
-	if err := tmpl.Execute(w, map[string]interface{} {"fortunes": fortunes}); err != nil {
+	fortuneStmts <- stmt //return a connection
+	fortunes = append(fortunes, &Fortune{Message: "Additional fortune added at request time."})
+
+	sort.Sort(ByMessage{fortunes})
+	w.Header().Set("Content-Type", "text/html")
+	if err := tmpl.Execute(w, map[string]interface{}{"fortunes": fortunes}); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 	}
 }
 
-type Fortunes []Fortune
+type Fortunes []*Fortune
+
 func (s Fortunes) Len() int      { return len(s) }
 func (s Fortunes) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
 type ByMessage struct{ Fortunes }
+
 func (s ByMessage) Less(i, j int) bool { return s.Fortunes[i].Message < s.Fortunes[j].Message }

+ 8 - 15
installer.py

@@ -87,7 +87,14 @@ class Installer:
     # go
     #
 
-    self.__run_command("curl http://go.googlecode.com/files/go1.1beta1.linux-amd64.tar.gz | tar xvz")
+    self.__run_command("curl http://go.googlecode.com/files/go1.1beta2.linux-amd64.tar.gz | tar xvz")
+
+    #
+    # Perl
+    #
+
+    self.__run_command("curl -L http://cpanmin.us | perl - --sudo App::cpanminus")
+    self.__run_command("cpanm -S DBI DBD::mysql Kelp Dancer Mojolicious Kelp::Module::JSON::XS Dancer::Plugin::Database Starman Plack JSON")
 
     #
     # php
@@ -128,20 +135,6 @@ class Installer:
     self.__run_command("sudo ringo-admin install oberhamsi/reinhardt")
     self.__run_command("sudo ringo-admin install grob/ringo-sqlstore")
 
-    #
-    # Perl
-    #
-    self.__run_command("sudo cpan install Plack", send_yes=True)
-    self.__run_command("sudo cpan install Starman")
-    self.__run_command("sudo cpan install DBD::mysql")
-    self.__run_command("sudo cpan install DBI")
-    self.__run_command("sudo cpan install Dancer")
-    self.__run_command("sudo cpan install Dancer::Plugin::Database")
-    self.__run_command("sudo cpan install JSON", send_yes=True)
-    self.__run_command("sudo cpan install Kelp", send_yes=True)
-    self.__run_command("sudo cpan install Mojolicious", send_yes=True)
-    self.__run_command("sudo cpan install Mojolicious:Plugin:Database", send_yes=True)
-
     #######################################
     # Webservers
     #######################################

+ 9 - 12
kelp/app.pl

@@ -2,12 +2,9 @@
 use Kelp::Less;
 use DBI;
 
-attr dbh => sub {
-    my $database = 'hello_world';
-    my $host     = 'localhost';
-    my $dsn      = 'dbi:mysql:database=hello_world;host=localhost;port=3306';
-    DBI->connect( $dsn, 'benchmarkdbuser', 'benchmarkdbpass', {} );
-};
+my $dsn = "dbi:mysql:database=hello_world;host=localhost;port=3306";
+my $dbh = DBI->connect( $dsn, 'benchmarkdbuser', 'benchmarkdbpass', {} );
+my $sth = $dbh->prepare("SELECT * FROM World where id = ?");
 
 get '/json' => sub {
     { message => 'Hello, World!' }
@@ -15,17 +12,17 @@ get '/json' => sub {
 
 get '/db' => sub {
     my $self = shift;
-    my $queries = param('queries') || 1;
+    my $queries = $self->param('queries') || 1;
     my @response;
-    my $sth = $self->dbh->prepare( 'SELECT randomnumber FROM world WHERE id = ?' );
     for ( 1 .. $queries ) {
         my $id = int rand 10000 + 1;
-        my $res = $sth->execute( $id );
-        if ( my $row = $sth->fetchrow_arrayref ) {
-            push @response, { id => $id, randomNumber => $row->[0] };
+        $sth->execute($id);
+        if ( my $row = $sth->fetchrow_hashref ) {
+            push @response,
+              { id => $id, randomNumber => $row->{randomNumber} };
         }
     }
-    { \@response }
+    return \@response;
 };
 
 run;

+ 1 - 2
kelp/benchmark_config

@@ -15,5 +15,4 @@
       "sort": 79
     }
   }]
-}
-
+}

+ 3 - 0
kelp/conf/config.pl

@@ -0,0 +1,3 @@
+{
+    modules => ['JSON::XS']
+}

+ 1 - 1
kelp/setup.py

@@ -24,7 +24,7 @@ def stop():
     p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
     out, err = p.communicate()
     for line in out.splitlines():
-      if 'plackup' in line:
+      if 'starman' in line:
         pid = int(line.split(None, 2)[1])
         os.kill(pid, 9)
     return 0

+ 8 - 10
mojolicious/app.pl

@@ -1,12 +1,10 @@
 #!/usr/bin/env perl
 use Mojolicious::Lite;
-use Mojolicious::Plugin::Database;
+use DBI;
 
-plugin 'database', {
-    dsn      => 'dbi:mysql:dbname=hello_world;host=localhost',
-    username => 'benchmarkdbuser',
-    password => 'benchmarkdbpass'
-};
+my $dsn = "dbi:mysql:database=hello_world;host=localhost;port=3306";
+my $dbh = DBI->connect( $dsn, 'benchmarkdbuser', 'benchmarkdbpass', {} );
+my $sth = $dbh->prepare("SELECT * FROM World where id = ?");
 
 get '/json' => sub {
     my $self = shift;
@@ -17,12 +15,12 @@ get '/db' => sub {
     my $self = shift;
     my $queries = $self->param('queries') || 1;
     my @response;
-    my $sth = $self->db->prepare( 'SELECT randomnumber FROM world WHERE id = ?' );
     for ( 1 .. $queries ) {
         my $id = int rand 10000 + 1;
-        my $res = $sth->execute( $id );
-        if ( my $row = $sth->fetchrow_arrayref ) {
-            push @response, { id => $id, randomNumber => $row->[0] };
+        $sth->execute($id);
+        if ( my $row = $sth->fetchrow_hashref ) {
+            push @response,
+              { id => $id, randomNumber => $row->{randomNumber} };
         }
     }
     $self->render( json => \@response );

+ 1 - 2
mojolicious/benchmark_config

@@ -15,5 +15,4 @@
       "sort": 81
     }
   }]
-}
-
+}

+ 1 - 1
mojolicious/setup.py

@@ -24,7 +24,7 @@ def stop():
     p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
     out, err = p.communicate()
     for line in out.splitlines():
-      if 'plackup' in line:
+      if 'starman' in line:
         pid = int(line.split(None, 2)[1])
         os.kill(pid, 9)
     return 0

+ 2 - 2
webgo/README.md

@@ -7,11 +7,11 @@ This is the webgo portion of a [benchmarking test suite](../) comparing a variet
 
 ## Versions
 
-* [Go 1.0.3](http://golang.org/)
+* [Go 1.1beta2](http://golang.org/)
 * [WebGo](https://github.com/hoisie/web)
 
 ## Test URLs
 
 ### JSON Encoding Test
 
-    http://localhost:8080/json
+    http://localhost:8080/json