Bladeren bron

fixes merge conflicts

Keith Newman 8 jaren geleden
bovenliggende
commit
72fe5aae4b
100 gewijzigde bestanden met toevoegingen van 1488 en 717 verwijderingen
  1. 7 6
      .github/PULL_REQUEST_TEMPLATE.md
  2. 1 4
      .travis.yml
  3. 19 0
      config/upstart.example/tfb.conf
  4. 8 7
      deployment/vagrant-aws/README.md
  5. 6 2
      deployment/vagrant-aws/setup_aws.py
  6. 13 9
      frameworks/C++/cpoll_cppsp/benchmark_config.json
  7. 2 1
      frameworks/C++/cutelyst/config/config_socket.ini
  8. 1 1
      frameworks/C++/cutelyst/nginx.conf
  9. 0 2
      frameworks/C++/cutelyst/setup.sh
  10. 0 2
      frameworks/C++/cutelyst/setup_thread.sh
  11. 0 2
      frameworks/C++/cutelyst/setup_uwsgi_nginx.sh
  12. 5 4
      frameworks/C++/ffead-cpp/benchmark_config.json
  13. 5 5
      frameworks/C++/poco/benchmark_config.json
  14. 9 6
      frameworks/C++/silicon/benchmark_config.json
  15. 8 6
      frameworks/C++/treefrog/benchmark_config.json
  16. 6 80
      frameworks/C++/ulib/benchmark_config.json
  17. 4 2
      frameworks/C++/ulib/setup_json.sh
  18. 8 4
      frameworks/C++/wt/benchmark_config.json
  19. 5 4
      frameworks/C/duda/benchmark_config.json
  20. 5 4
      frameworks/C/h2o/benchmark_config.json
  21. 4 3
      frameworks/C/haywire/benchmark_config.json
  22. 3 2
      frameworks/C/libreactor/benchmark_config.json
  23. 12 9
      frameworks/C/lwan/benchmark_config.json
  24. 8 6
      frameworks/C/onion/benchmark_config.json
  25. 25 21
      frameworks/CSharp/HttpListener/benchmark_config.json
  26. 25 20
      frameworks/CSharp/aspnet-stripped/benchmark_config.json
  27. 98 80
      frameworks/CSharp/aspnet/benchmark_config.json
  28. 1 0
      frameworks/CSharp/aspnetcore/Benchmarks/Configuration/AppSettings.cs
  29. 12 0
      frameworks/CSharp/aspnetcore/Benchmarks/Configuration/DatabaseServer.cs
  30. 30 12
      frameworks/CSharp/aspnetcore/Benchmarks/Configuration/Scenarios.cs
  31. 11 51
      frameworks/CSharp/aspnetcore/Benchmarks/Controllers/FortunesController.cs
  32. 42 0
      frameworks/CSharp/aspnetcore/Benchmarks/Controllers/MultipleQueriesController.cs
  33. 42 0
      frameworks/CSharp/aspnetcore/Benchmarks/Controllers/MultipleUpdatesController.cs
  34. 41 0
      frameworks/CSharp/aspnetcore/Benchmarks/Controllers/SingleQueryController.cs
  35. 49 2
      frameworks/CSharp/aspnetcore/Benchmarks/Data/ApplicationDbContext.cs
  36. 24 0
      frameworks/CSharp/aspnetcore/Benchmarks/Data/BatchUpdateString.cs
  37. 50 12
      frameworks/CSharp/aspnetcore/Benchmarks/Data/DapperDb.cs
  38. 27 3
      frameworks/CSharp/aspnetcore/Benchmarks/Data/EfDb.cs
  39. 4 0
      frameworks/CSharp/aspnetcore/Benchmarks/Data/Fortune.cs
  40. 19 0
      frameworks/CSharp/aspnetcore/Benchmarks/Data/IDb.cs
  41. 43 0
      frameworks/CSharp/aspnetcore/Benchmarks/Data/NoTransactionSqlServerConnection.cs
  42. 6 3
      frameworks/CSharp/aspnetcore/Benchmarks/Data/Random.cs
  43. 89 39
      frameworks/CSharp/aspnetcore/Benchmarks/Data/RawDb.cs
  44. 5 0
      frameworks/CSharp/aspnetcore/Benchmarks/Data/World.cs
  45. 0 47
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/ErrorHandlerMiddleware.cs
  46. 5 5
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/FortunesEfMiddleware.cs
  47. 14 5
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MiddlewareHelpers.cs
  48. 5 5
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleQueriesEfMiddleware.cs
  49. 61 0
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesDapperMiddleware.cs
  50. 61 0
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesEfMiddleware.cs
  51. 61 0
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesRawMiddleware.cs
  52. 5 5
      frameworks/CSharp/aspnetcore/Benchmarks/Middleware/SingleQueryEfMiddleware.cs
  53. 2 2
      frameworks/CSharp/aspnetcore/Benchmarks/NuGet.Config
  54. 41 8
      frameworks/CSharp/aspnetcore/Benchmarks/Startup.cs
  55. 0 3
      frameworks/CSharp/aspnetcore/Benchmarks/appsettings.json
  56. 4 0
      frameworks/CSharp/aspnetcore/Benchmarks/appsettings.postgresql.json
  57. 21 10
      frameworks/CSharp/aspnetcore/Benchmarks/project.json
  58. 185 10
      frameworks/CSharp/aspnetcore/benchmark_config.json
  59. 10 2
      frameworks/CSharp/aspnetcore/run-linux.sh
  60. 3 0
      frameworks/CSharp/aspnetcore/setup-dapper.sh
  61. 3 0
      frameworks/CSharp/aspnetcore/setup-ef.sh
  62. 3 0
      frameworks/CSharp/aspnetcore/setup-json.sh
  63. 0 3
      frameworks/CSharp/aspnetcore/setup-mvc.sh
  64. 3 0
      frameworks/CSharp/aspnetcore/setup-plaintext.sh
  65. 3 0
      frameworks/CSharp/aspnetcore/setup-raw.sh
  66. 0 3
      frameworks/CSharp/aspnetcore/setup.sh
  67. 3 2
      frameworks/CSharp/evhttp-sharp/benchmark_config.json
  68. 6 4
      frameworks/CSharp/nancy/benchmark_config.json
  69. 15 13
      frameworks/CSharp/revenj/benchmark_config.json
  70. 58 44
      frameworks/CSharp/servicestack/benchmark_config.json
  71. 2 1
      frameworks/Clojure/aleph/benchmark_config.json
  72. 2 0
      frameworks/Clojure/compojure/benchmark_config.json
  73. 8 6
      frameworks/Clojure/http-kit/benchmark_config.json
  74. 4 3
      frameworks/Clojure/luminus/benchmark_config.json
  75. 4 3
      frameworks/Clojure/pedestal/benchmark_config.json
  76. 5 4
      frameworks/Crystal/crystal/benchmark_config.json
  77. 0 0
      frameworks/Crystal/crystal/server.cr
  78. 0 0
      frameworks/Crystal/crystal/setup.sh
  79. 6 4
      frameworks/Crystal/kemal/benchmark_config.json
  80. 4 27
      frameworks/Crystal/kemal/server-postgres.cr
  81. 2 25
      frameworks/Crystal/kemal/server-redis.cr
  82. 2 2
      frameworks/Crystal/kemal/setup-postgres.sh
  83. 2 2
      frameworks/Crystal/kemal/setup-redis.sh
  84. 2 2
      frameworks/Crystal/kemal/shard.lock
  85. 3 5
      frameworks/Crystal/kemal/shard.yml
  86. 20 0
      frameworks/Crystal/kemal/views/fortunes.ecr
  87. 6 4
      frameworks/D/vibed/benchmark_config.json
  88. 4 3
      frameworks/Dart/dart-raw/benchmark_config.json
  89. 6 4
      frameworks/Dart/redstone/benchmark_config.json
  90. 4 2
      frameworks/Dart/start/benchmark_config.json
  91. 4 2
      frameworks/Dart/stream/benchmark_config.json
  92. 7 6
      frameworks/Elixir/cowboy/benchmark_config.json
  93. 4 3
      frameworks/Elixir/phoenix/benchmark_config.json
  94. 4 3
      frameworks/Erlang/chicagoboss/benchmark_config.json
  95. 5 4
      frameworks/Erlang/cowboy/benchmark_config.json
  96. 4 3
      frameworks/Erlang/elli/benchmark_config.json
  97. 4 3
      frameworks/Erlang/mochiweb/benchmark_config.json
  98. 2 1
      frameworks/Go/beego/benchmark_config.json
  99. 13 10
      frameworks/Go/echo/benchmark_config.json
  100. 1 0
      frameworks/Go/echo/setup.sh

+ 7 - 6
.github/PULL_REQUEST_TEMPLATE.md

@@ -6,13 +6,14 @@ REQUEST AGAINST THE CORRECT BRANCH
 
 ....................................
 
-master = bug fixes directly
-addressing the current preview round
+master = currently not accepting pull
+requests as we prepare for our Round 13
+final release.
 
-round-X = new features, frameworks,
-tests, and any other larger changes
-that you would like to see in the
-next round
+round-14 = new features, frameworks, 
+tests, bug fixes, and any other 
+changes that you would like to see in 
+the next round.
 
 ....................................
 -->

+ 1 - 4
.travis.yml

@@ -68,7 +68,6 @@ env:
     - "TESTDIR=Haskell/snap"
     - "TESTDIR=Haskell/wai"
     - "TESTDIR=Haskell/yesod"
-    - "TESTDIR=Haskell/yesod-postgres"
     - "TESTDIR=Haskell/servant"
     - "TESTDIR=Haskell/spock"
     - "TESTDIR=Java/activeweb"
@@ -101,7 +100,6 @@ env:
     - "TESTDIR=Java/spring"
     - "TESTDIR=Java/tapestry"
     - "TESTDIR=Java/undertow"
-    - "TESTDIR=Java/undertow-edge"
     - "TESTDIR=Java/undertow-jersey-c3p0"
     - "TESTDIR=Java/undertow-jersey-hikaricp"
     - "TESTDIR=Java/vertx"
@@ -130,7 +128,7 @@ env:
     - "TESTDIR=PHP/cakephp"
     - "TESTDIR=PHP/hhvm"
     - "TESTDIR=PHP/php"
-    - "TESTDIR=PHP/cygnite-php-framework"
+    - "TESTDIR=PHP/cygnite"
     - "TESTDIR=PHP/codeigniter"
     - "TESTDIR=PHP/clancats"
     - "TESTDIR=PHP/fat-free"
@@ -193,7 +191,6 @@ env:
     - "TESTDIR=Scala/scruffy"
     - "TESTDIR=Scala/spray"
     - "TESTDIR=Scala/s-server"
-    - "TESTDIR=Scala/spray-es"
     - "TESTDIR=Scala/unfiltered"
     - "TESTDIR=Scala/http4s"
     - "TESTDIR=Scala/finch"

+ 19 - 0
config/upstart.example/tfb.conf

@@ -0,0 +1,19 @@
+# /etc/init/tfb.conf
+env TFB_REPOPARENT="/private"
+env TFB_REPONAME="FrameworkBenchmarks"
+env TFB_REPOURI="https://github.com/ashawnbandy-te-tfb/FrameworkBenchmarks.git"
+env TFB_MAILINGLIST="[email protected]"
+env TFB_MAILING_FROM="[email protected]"
+env TFB_LOGSFOLDER="/private/logs"
+env TFB_REPOBRANCH="45216-continuousbenchmarking-20160609-asb-2"
+setuid techempower
+setgid techempower
+umask 0002
+respawn
+respawn limit 5 2
+script
+  if [ ! -d "$TFB_REPOPARENT/$TFB_REPONAME" ]; then
+    git clone -b $TFB_REPOBRANCH $TFB_REPOURI $TFB_REPOPARENT/$TFB_REPONAME
+  fi
+  exec /$TFB_REPOPARENT/$TFB_REPONAME/toolset/run-continuously.sh
+end script

+ 8 - 7
deployment/vagrant-aws/README.md

@@ -29,12 +29,13 @@ too old, download the newest `deb` directly). See
 
 ## Using Vagrant to Run Amazon-powered Virtual Machine
 
-The high level steps are 
-1) clone this project 
-2) set environment variables allowing us to log into your amazon account
-3) Run amazon setup script to create network
-4) Run `vagrant up --provider=aws` to launch into amazon
-5) Run `vagrant ssh` to log into the application server
+The high level steps are:
+
+* clone this project 
+* set environment variables allowing us to log into your amazon account
+* Run amazon setup script to create network
+* Run `vagrant up --provider=aws` to launch into amazon
+* Run `vagrant ssh` to log into the application server
 
 By default, your local git clone of this project will not by synced with the 
 remote amazon machines.
@@ -189,7 +190,7 @@ simultaneous benchmarks, so the better approach is to just increase all
 the IP addresses by 3 and run the additional benchmarks in the same VPC. 
 
 
-**I'm getting an AuthFailure but my Credientials are Correct!**:
+**I'm getting an AuthFailure but my Credentials are Correct!**:
 
 This normally means the AMI has been moved from public to private. Ubuntu's 
 Cloud image team occasionally does this. Navigate [here](http://cloud-images.ubuntu.com/trusty/current/) and find a more current AMI. 

+ 6 - 2
deployment/vagrant-aws/setup_aws.py

@@ -101,8 +101,12 @@ def run_aws(command, prefix=True, load=True):
   log.debug("Request : %s", command)
   result = subprocess.check_output(command, shell=True)
   log.debug("Response: %s", result)
-  if load:
-    return json.loads(result)
+  if load and result != '':
+    try:
+      return json.loads(result)
+    except ValueError:
+      log.error("Could not parse result '%s' as JSON for command '%s'", result, command)
+      raise
   else:
     return result
 

+ 13 - 9
frameworks/C++/cpoll_cppsp/benchmark_config.json

@@ -7,18 +7,19 @@
       "plaintext_url": "/plaintext",
       "port": 16969,
       "approach": "Realistic",
-      "classification": "Micro",
+      "classification": "Platform",
       "database": "None",
       "framework": "cpoll-cppsp",
       "language": "C++",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "CPoll",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "cpoll-cppsp",
       "notes": "",
-      "versus": ""
+      "versus": "cpoll_cppsp"
     },
     "raw": {
       "setup_file": "setup",
@@ -32,14 +33,15 @@
       "database": "MySQL",
       "framework": "cpoll-cppsp",
       "language": "C++",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "CPoll",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "cpoll-cppsp-raw",
       "notes": "",
-      "versus": ""
+      "versus": "cpoll_cppsp"
     },
     "postgres-raw": {
       "setup_file": "setup",
@@ -51,14 +53,15 @@
       "database": "Postgres",
       "framework": "cpoll-cppsp",
       "language": "C++",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "CPoll",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "cpoll-cppsp-raw",
       "notes": "",
-      "versus": ""
+      "versus": "cpoll_cppsp"
     },
     "postgres-raw-threadpool": {
       "setup_file": "setup",
@@ -70,14 +73,15 @@
       "database": "Postgres",
       "framework": "cpoll-cppsp",
       "language": "C++",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "CPoll",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "cpoll-pool",
       "notes": "Threadpool",
-      "versus": ""
+      "versus": "cpoll_cppsp"
     }
   }]
 }

+ 2 - 1
frameworks/C++/cutelyst/config/config_socket.ini

@@ -3,9 +3,10 @@ master
 ; Increase listen queue used for nginx connecting to uWSGI. This matches
 ; net.ipv4.tcp_max_syn_backlog and net.core.somaxconn.
 ; for performance
+listen = 65535
 disable-logging
 ; use UNIX sockets instead of TCP loopback for performance
-socket = /tmp/uwsgi.sock
+socket = /var/tmp/uwsgi.sock
 ; allow nginx to access the UNIX socket
 chmod-socket = 666
 ; Avoid thundering herd problem http://uwsgi-docs.readthedocs.org/en/latest/articles/SerializingAccept.html .

+ 1 - 1
frameworks/C++/cutelyst/nginx.conf

@@ -41,7 +41,7 @@ http {
         server_name  localhost;
 
         location / {
-            uwsgi_pass unix:/tmp/uwsgi.sock;
+            uwsgi_pass unix:/var/tmp/uwsgi.sock;
             include /usr/local/nginx/conf/uwsgi_params;
         }
     }

+ 0 - 2
frameworks/C++/cutelyst/setup.sh

@@ -8,14 +8,12 @@ sed -i 's|SendDate=.*|SendDate=false|g' config/config.ini
 cd $IROOT
 mkdir cutelyst-benchmarks || true
 cd cutelyst-benchmarks
-rm -rf *
 
 QT_VERSION_MM=56
 export CMAKE_PREFIX_PATH=/opt/qt${QT_VERSION_MM}:${IROOT}
 
 cmake $TROOT -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$IROOT
 
-make clean
 make -j $MAX_THREADS
 
 export LD_LIBRARY_PATH=/opt/qt${QT_VERSION_MM}/lib:${IROOT}/lib/x86_64-linux-gnu/

+ 0 - 2
frameworks/C++/cutelyst/setup_thread.sh

@@ -8,14 +8,12 @@ sed -i 's|SendDate=.*|SendDate=false|g' config/config.ini
 cd $IROOT
 mkdir cutelyst-benchmarks || true
 cd cutelyst-benchmarks
-rm -rf *
 
 QT_VERSION_MM=56
 export CMAKE_PREFIX_PATH=/opt/qt${QT_VERSION_MM}:${IROOT}
 
 cmake $TROOT -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$IROOT
 
-make clean
 make -j $MAX_THREADS
 
 export LD_LIBRARY_PATH=/opt/qt${QT_VERSION_MM}/lib:${IROOT}/lib/x86_64-linux-gnu/

+ 0 - 2
frameworks/C++/cutelyst/setup_uwsgi_nginx.sh

@@ -9,14 +9,12 @@ sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_par
 cd $IROOT
 mkdir cutelyst-benchmarks || true
 cd cutelyst-benchmarks
-rm -rf *
 
 QT_VERSION_MM=56
 export CMAKE_PREFIX_PATH=/opt/qt${QT_VERSION_MM}:${IROOT}
 
 cmake $TROOT -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$IROOT
 
-make clean
 make -j $MAX_THREADS
 
 nginx -c $TROOT/nginx.conf

+ 5 - 4
frameworks/C++/ffead-cpp/benchmark_config.json

@@ -11,12 +11,13 @@
       "update_url": "/te-benchmark/updates?queries=",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Fullstack",
-      "database": "mongodb",
+      "classification": "micro",
+      "database": "MongoDB",
       "framework": "ffead-cpp",
       "language": "C++",
+      "flavor": "None",
       "orm": "Full",
-      "platform": "ffead-cpp",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
@@ -206,7 +207,7 @@
       "database_os": "Linux",
       "display_name": "ffead-cpp-nginx-postgresql",
       "notes": "",
-      "versus": ""
+      "versus": "ffead-cpp"
     }
   }]
 }

+ 5 - 5
frameworks/C++/poco/benchmark_config.json

@@ -8,17 +8,17 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "none",
-      "framework": "POCO",
+      "framework": "None",
       "language": "C++",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "POCO",
-      "webserver": "poco",
+      "platform": "None",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "POCO",
       "notes": "",
-      "versus": ""
+      "versus": "poco"
     }
   }]
 }
-

+ 9 - 6
frameworks/C++/silicon/benchmark_config.json

@@ -15,14 +15,15 @@
       "database": "MySQL",
       "framework": "silicon",
       "language": "C++",
+      "flavor": "None",
       "orm": "Full",
-      "platform": "Silicon",
+      "platform": "None",
       "webserver": "microhttpd",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "silicon-tpc-mysql",
       "notes": "",
-      "versus": ""
+      "versus": "silicon"
     },
     "epoll-mysql": {
       "setup_file": "setup_mhd_epoll_mysql",
@@ -38,14 +39,15 @@
       "database": "MySQL",
       "framework": "silicon",
       "language": "C++",
+      "flavor": "None",
       "orm": "Full",
-      "platform": "Silicon",
+      "platform": "None",
       "webserver": "microhttpd",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "silicon-epoll-mysql",
       "notes": "",
-      "versus": ""
+      "versus": "silicon"
     },
     "lwan-mysql": {
       "setup_file": "setup_lwan_mysql",
@@ -61,14 +63,15 @@
       "database": "MySQL",
       "framework": "silicon",
       "language": "C++",
+      "flavor": "None",
       "orm": "Full",
-      "platform": "Silicon",
+      "platform": "None",
       "webserver": "Lwan",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "silicon-lwan-mysql",
       "notes": "",
-      "versus": ""
+      "versus": "silicon"
     }
     
   }]

+ 8 - 6
frameworks/C++/treefrog/benchmark_config.json

@@ -16,7 +16,7 @@
       "framework": "treefrog",
       "language": "C++",
       "orm": "Micro",
-      "platform": "Treefrog",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
@@ -38,14 +38,15 @@
       "database": "MySQL",
       "framework": "treefrog",
       "language": "C++",
+      "flavor": "None",
       "orm": "Micro",
-      "platform": "Treefrog",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "treefrog-hybrid",
       "notes": "",
-      "versus": ""
+      "versus": "treefrog"
     },
     "postgres": {
       "setup_file": "setup-postgres",
@@ -61,8 +62,9 @@
       "database": "Postgres",
       "framework": "treefrog",
       "language": "C++",
+      "flavor": "None",
       "orm": "Micro",
-      "platform": "Treefrog",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
@@ -85,13 +87,13 @@
       "framework": "treefrog",
       "language": "C++",
       "orm": "Micro",
-      "platform": "Treefrog",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "treefrog-mongo",
       "notes": "",
-      "versus": ""
+      "versus": "treefrog"
     }
   }]
 }

+ 6 - 80
frameworks/C++/ulib/benchmark_config.json

@@ -11,7 +11,7 @@
       "framework": "ULib",
       "language": "C++",
       "orm": "Micro",
-      "platform": "ULib",
+      "platform": "None",
       "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
@@ -19,7 +19,7 @@
       "notes": "",
       "versus": ""
     },
-    "json_normal": {
+    "json": {
       "setup_file": "setup_json",
       "json_url": "/json",
       "port": 8080,
@@ -29,61 +29,7 @@
       "framework": "ULib",
       "language": "C++",
       "orm": "Micro",
-      "platform": "ULib",
-      "webserver": "ULib",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "ULib",
-      "notes": "",
-      "versus": ""
-    },
-    "json_medium": {
-      "setup_file": "setup_json_medium",
-      "json_url": "/json",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Platform",
-      "database": "None",
-      "framework": "ULib",
-      "language": "C++",
-      "orm": "Micro",
-      "platform": "ULib",
-      "webserver": "ULib",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "ULib",
-      "notes": "",
-      "versus": ""
-    },
-    "json_large": {
-      "setup_file": "setup_json_large",
-      "json_url": "/json",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Platform",
-      "database": "None",
-      "framework": "ULib",
-      "language": "C++",
-      "orm": "Micro",
-      "platform": "ULib",
-      "webserver": "ULib",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "ULib",
-      "notes": "",
-      "versus": ""
-    },
-    "json_extra": {
-      "setup_file": "setup_json_extra",
-      "json_url": "/json",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Platform",
-      "database": "None",
-      "framework": "ULib",
-      "language": "C++",
-      "orm": "Micro",
-      "platform": "ULib",
+      "platform": "None",
       "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
@@ -104,7 +50,7 @@
       "framework": "ULib",
       "language": "C++",
       "orm": "Micro",
-      "platform": "ULib",
+      "platform": "None",
       "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
@@ -125,7 +71,7 @@
       "framework": "ULib",
       "language": "C++",
       "orm": "Micro",
-      "platform": "ULib",
+      "platform": "None",
       "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
@@ -133,26 +79,6 @@
       "notes": "",
       "versus": ""
     },
-    "sqlite": {
-      "setup_file": "setup_sqlite",
-      "db_url": "/db",
-      "query_url": "/query?queries=",
-      "fortune_url": "/fortune",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Platform",
-      "database": "SQLite",
-      "framework": "ULib",
-      "language": "C++",
-      "orm": "Micro",
-      "platform": "ULib",
-      "webserver": "ULib",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "ULib-sqlite",
-      "notes": "",
-      "versus": ""
-    },
     "mongodb": {
       "setup_file": "setup_mongodb",
       "db_url": "/mdb",
@@ -166,7 +92,7 @@
       "framework": "ULib",
       "language": "C++",
       "orm": "Micro",
-      "platform": "ULib",
+      "platform": "None",
       "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",

+ 4 - 2
frameworks/C++/ulib/setup_json.sh

@@ -2,8 +2,10 @@
 
 fw_depends ulib
 
-# Travis is really broken!!
-if [ "$TRAVIS" == "true" ]; then
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+else
 MAX_THREADS=$(( 2 * $MAX_THREADS ))
 fi
 

+ 8 - 4
frameworks/C++/wt/benchmark_config.json

@@ -15,13 +15,15 @@
      	"database": "MySQL",
      	"framework": "wt",
      	"language": "C++",
+          "flavor": "None",
      	"orm": "Full",
-     	"platform": "Wt",
+     	"platform": "None",
      	"webserver": "None",
      	"os": "Linux",
      	"database_os": "Linux",
      	"display_name": "wt",
-     	"notes": ""
+     	"notes": "",
+          "versus": "wt"
      },
      "postgres": {
      	"setup_file": "setup_postgres",
@@ -35,13 +37,15 @@
      	"database": "Postgres",
      	"framework": "wt",
      	"language": "C++",
+          "flavor": "None",
      	"orm": "Full",
-     	"platform": "Wt",
+     	"platform": "None",
      	"webserver": "None",
      	"os": "Linux",
      	"database_os": "Linux",
      	"display_name": "wt-postgres",
-     	"notes": ""
+     	"notes": "",
+          "versus": "wt"
      }
   }]
 }

+ 5 - 4
frameworks/C/duda/benchmark_config.json

@@ -8,17 +8,18 @@
       "port": 2001,
       "approach": "Realistic",
       "classification": "Platform",
-      "database": "none",
-      "framework": "Duda",
+      "database": "None",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Duda I/O",
+      "platform": "duda",
       "webserver": "Monkey",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "Duda I/O",
       "notes": "",
-      "versus": ""
+      "versus": "duda"
     }
   }]
 }

+ 5 - 4
frameworks/C/h2o/benchmark_config.json

@@ -13,14 +13,15 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "Postgres",
-      "framework": "H2O",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "H2O",
-      "webserver": "H2O",
+      "platform": "None",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "h2o",
+      "display_name": "H2O",
       "notes": ""
     }
   }]

+ 4 - 3
frameworks/C/haywire/benchmark_config.json

@@ -6,17 +6,18 @@
       "plaintext_url": "/plaintext",
       "port": 8000,
       "approach": "Realistic",
-      "classification": "Micro",
+      "classification": "Platform",
       "database": "None",
-      "framework": "haywire",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
       "platform": "haywire",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "notes": "",
-      "versus": ""
+      "versus": "haywire"
     }
   }]
 }

+ 3 - 2
frameworks/C/libreactor/benchmark_config.json

@@ -9,15 +9,16 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "None",
-      "framework": "libreactor",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
       "platform": "libreactor",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "notes": "",
-      "versus": ""
+      "versus": "libreactor"
     }
   }]
 }

+ 12 - 9
frameworks/C/lwan/benchmark_config.json

@@ -9,16 +9,17 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "None",
-      "framework": "lwan",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
       "platform": "Lwan",
-      "webserver": "Lwan",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "Lwan",
       "notes": "",
-      "versus": ""
+      "versus": "lwan"
     },
     "sqlite": {
       "setup_file": "setup",
@@ -29,16 +30,17 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "SQLite",
-      "framework": "lwan",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
       "platform": "Lwan",
-      "webserver": "Lwan",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "Lwan",
       "notes": "",
-      "versus": ""
+      "versus": "lwan"
     },
     "mysql": {
       "setup_file": "setup-mysql",
@@ -49,16 +51,17 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "MySQL",
-      "framework": "lwan",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
       "platform": "Lwan",
-      "webserver": "Lwan",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "Lwan",
       "notes": "",
-      "versus": ""
+      "versus": "lwan"
     }
   }]
 }

+ 8 - 6
frameworks/C/onion/benchmark_config.json

@@ -8,16 +8,17 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "None",
-      "framework": "onion",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Onion",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "onion",
       "notes": "",
-      "versus": ""
+      "versus": "onion"
     },
     "raw": {
       "setup_file": "setup",
@@ -28,16 +29,17 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "MySQL",
-      "framework": "onion",
+      "framework": "None",
       "language": "C",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Onion",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "onion",
       "notes": "",
-      "versus": ""
+      "versus": "onion"
     }
   }]
 }

+ 25 - 21
frameworks/CSharp/HttpListener/benchmark_config.json

@@ -6,19 +6,20 @@
       "json_url": "/json",
       "plaintext_url": "/plaintext",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "None",
-      "framework": "http-listener",
+      "framework": "None",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
-      "webserver": "HTTP.sys",
+      "platform": "None",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "http-listener",
       "notes": "",
-      "versus": ""
+      "versus": "HttpListener"
     },
     "mysql-raw": {
       "setup_file": "setup",
@@ -27,14 +28,15 @@
       "fortune_url": "/fortunes?provider=mysql",
       "update_url": "/updates?provider=mysql&queries=",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "MySQL",
-      "framework": "http-listener",
+      "framework": "None",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
-      "webserver": "HTTP.sys",
+      "platform": "None",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "http-listener",
@@ -48,14 +50,14 @@
       "fortune_url": "/fortunes?provider=postgresql",
       "update_url": "/updates?provider=postgresql&queries=",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "Postgres",
-      "framework": "http-listener",
+      "framework": "None",
       "language": "C#",
       "orm": "Raw",
-      "platform": "NET",
-      "webserver": "HTTP.sys",
+      "platform": "None",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "http-listener",
@@ -69,14 +71,15 @@
       "fortune_url": "/mongodbfortunes",
       "update_url": "/mongodbupdates?queries=",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "MongoDB",
-      "framework": "http-listener",
+      "framework": "None",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
-      "webserver": "HTTP.sys",
+      "platform": "None",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "http-listener",
@@ -90,14 +93,15 @@
       "fortune_url": "/fortunes?provider=sqlserver",
       "update_url": "/updates?provider=sqlserver&queries=",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "SQLServer",
-      "framework": "http-listener",
+      "framework": "None",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
-      "webserver": "HTTP.sys",
+      "platform": "None",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Windows",
       "display_name": "http-listener",

+ 25 - 20
frameworks/CSharp/aspnet-stripped/benchmark_config.json

@@ -9,16 +9,17 @@
       "approach": "Stripped",
       "classification": "Fullstack",
       "database": "None",
-      "framework": "aspnet",
+      "framework": "ASP.NET",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-stripped",
+      "display_name": "asp.net-stripped",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet-stripped"
     },
     "mysql-raw": {
       "setup_file": "setup_iis",
@@ -30,16 +31,17 @@
       "approach": "Stripped",
       "classification": "Fullstack",
       "database": "MySQL",
-      "framework": "aspnet",
+      "framework": "ASP.NET",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-stripped-raw",
+      "display_name": "asp.net-stripped-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet-stripped"
     },
     "postgresql-raw": {
       "setup_file": "setup_iis",
@@ -51,16 +53,17 @@
       "approach": "Stripped",
       "classification": "Fullstack",
       "database": "Postgres",
-      "framework": "aspnet",
+      "framework": "ASP.NET",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-stripped-raw",
+      "display_name": "asp.net-stripped-raw",
       "notes": "",
-      "versus": ""
+      "versus": "asnet-stripped"
     },
     "mongodb-raw": {
       "setup_file": "setup_iis",
@@ -72,16 +75,17 @@
       "approach": "Stripped",
       "classification": "Fullstack",
       "database": "MongoDB",
-      "framework": "aspnet",
+      "framework": "ASP.NET",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-stripped-raw",
+      "display_name": "asp.net-stripped-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet-stripped"
     },
     "sqlserver-raw": {
       "setup_file": "setup_iis",
@@ -93,16 +97,17 @@
       "approach": "Stripped",
       "classification": "Fullstack",
       "database": "SQLServer",
-      "framework": "aspnet",
+      "framework": "ASP.NET",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Windows",
-      "display_name": "aspnet-stripped-raw",
+      "display_name": "asp.net-stripped-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet-stripped"
     }
   }]
 }

+ 98 - 80
frameworks/CSharp/aspnet/benchmark_config.json

@@ -9,52 +9,55 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "None",
-      "framework": "aspnet-mvc",
+      "framework": "asp.net",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet",
+      "display_name": "asp.net",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "jsonnet": {
       "setup_file": "setup_iis",
       "json_url": "/json/jsonnet",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "None",
-      "framework": "aspnet",
+      "framework": "asp.net",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-jsonnet",
+      "display_name": "jsonnet",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "servicestack": {
       "setup_file": "setup_iis",
       "json_url": "/json/servicestack",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "None",
-      "framework": "aspnet",
+      "framework": "asp.net",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-svcstk",
+      "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "mysql-raw": {
       "setup_file": "setup_iis",
@@ -66,16 +69,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "MySQL",
-      "framework": "aspnet-mvc",
+      "framework": "asp.net",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-raw",
+      "display_name": "asp.net-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "postgresql-raw": {
       "setup_file": "setup_iis",
@@ -87,16 +91,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "Postgres",
-      "framework": "aspnet-mvc",
+      "framework": "asp.net",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-raw",
+      "display_name": "asp.net-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "mongodb-raw": {
       "setup_file": "setup_iis",
@@ -108,16 +113,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "MongoDB",
-      "framework": "aspnet-mvc",
+      "framework": "asp.net",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-raw",
+      "display_name": "asp.net-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "sqlserver-raw": {
       "setup_file": "setup_iis",
@@ -129,16 +135,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "SQLServer",
-      "framework": "aspnet-mvc",
+      "framework": "asp.net-mvc",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Windows",
-      "display_name": "aspnet-mvc-raw",
+      "display_name": "aspnet-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "mysql-entityframework": {
       "setup_file": "setup_iis",
@@ -150,16 +157,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "MySQL",
-      "framework": "aspnet-mvc",
+      "framework": "EntityFramework",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Full",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc",
+      "display_name": "EntityFramework",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "postgresql-entityframework": {
       "setup_file": "setup_iis",
@@ -171,16 +179,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "Postgres",
-      "framework": "aspnet-mvc",
+      "framework": "EntityFramework",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Full",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc",
+      "display_name": "EntityFramework",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "sqlserver-entityframework": {
       "setup_file": "setup_iis",
@@ -192,16 +201,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "SQLServer",
-      "framework": "aspnet-mvc",
+      "framework": "EntityFramework",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Full",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Windows",
-      "display_name": "aspnet-mvc",
+      "display_name": "EntityFramework",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "mono": {
       "setup_file": "setup_nginx",
@@ -209,54 +219,57 @@
       "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Fullstack",
+      "classification": "Platform",
       "database": "None",
-      "framework": "aspnet-mvc",
+      "framework": "None",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "ASP.NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-mono",
+      "display_name": "ASP.NET",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet-mono"
     },
     "mono-jsonnet": {
       "setup_file": "setup_nginx",
       "json_url": "/json/jsonnet",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "None",
-      "framework": "aspnet",
+      "framework": "JSONNet",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "ASP.NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "aspnet-jsonnet-mono",
+      "display_name": "JSONNet",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet-mono"
     },
     "mono-servicestack": {
       "setup_file": "setup_nginx",
       "json_url": "/json/servicestack",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "None",
-      "framework": "aspnet",
+      "framework": "ServiceStack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "ASP.NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "aspnet-svcstk-mono",
+      "display_name": "ServiceStack",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet-mono"
     },
     "mono-mysql-raw": {
       "setup_file": "setup_nginx",
@@ -268,18 +281,19 @@
       "update_url": "/ado/mysql/update?queries=",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Fullstack",
+      "classification": "Platform",
       "database": "MySQL",
-      "framework": "aspnet-mvc",
+      "framework": "None",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "ASP.NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-mono-raw",
+      "display_name": "ASP.NET-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "mono-postgresql-raw": {
       "setup_file": "setup_nginx",
@@ -289,18 +303,19 @@
       "update_url": "/ado/postgresql/update?queries=",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Fullstack",
+      "classification": "Platform",
       "database": "Postgres",
-      "framework": "aspnet-mvc",
+      "framework": "None",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "ASP.NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-mono-raw",
+      "display_name": "ASP.NET-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "mono-mongodb-raw": {
       "setup_file": "setup_nginx",
@@ -310,18 +325,19 @@
       "update_url": "/mongodb/update?queries=",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Fullstack",
+      "classification": "Platform",
       "database": "MongoDB",
-      "framework": "aspnet-mvc",
+      "framework": "None",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "ASP.NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-mono-raw",
+      "display_name": "aspnet-raw",
       "notes": "",
-      "versus": ""
+      "versus": "aspnet"
     },
     "mono-mysql-entityframework": {
       "setup_file": "setup_nginx",
@@ -333,16 +349,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "MySQL",
-      "framework": "aspnet-mvc",
+      "framework": "EntityFramework",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Full",
-      "platform": "Mono",
+      "platform": "ASP.NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-mono",
+      "display_name": "EntityFramework",
       "notes": "Entity framework",
-      "versus": ""
+      "versus": "aspnet"
     },
     "mono-postgresql-entityframework": {
       "setup_file": "setup_nginx",
@@ -354,16 +371,17 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "Postgres",
-      "framework": "aspnet-mvc",
+      "framework": "EntityFramework",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Full",
-      "platform": "Mono",
+      "platform": "ASP.NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "aspnet-mvc-mono",
+      "display_name": "EntityFramework",
       "notes": "Entity framework",
-      "versus": ""
+      "versus": "aspnet"
     }
   }]
 }

+ 1 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Configuration/AppSettings.cs

@@ -7,5 +7,6 @@ namespace Benchmarks.Configuration
     public class AppSettings
     {
         public string ConnectionString { get; set; }
+        public DatabaseServer Database { get; set; } = DatabaseServer.SqlServer;
     }
 }

+ 12 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Configuration/DatabaseServer.cs

@@ -0,0 +1,12 @@
+// Copyright (c) .NET Foundation. All rights reserved. 
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
+
+
+namespace Benchmarks.Configuration
+{
+    public enum DatabaseServer
+    {
+        SqlServer,
+        PostgreSql
+    }
+}

+ 30 - 12
frameworks/CSharp/aspnetcore/Benchmarks/Configuration/Scenarios.cs

@@ -44,6 +44,15 @@ namespace Benchmarks.Configuration
         [ScenarioPath("/queries/dapper")]
         public bool DbMultiQueryDapper { get; set; }
 
+        [ScenarioPath("/updates/raw")]
+        public bool DbMultiUpdateRaw { get; set; }
+
+        [ScenarioPath("/updates/ef")]
+        public bool DbMultiUpdateEf { get; set; }
+
+        [ScenarioPath("/updates/dapper")]
+        public bool DbMultiUpdateDapper { get; set; }
+
         [ScenarioPath("/fortunes/raw")]
         public bool DbFortunesRaw { get; set; }
 
@@ -62,23 +71,32 @@ namespace Benchmarks.Configuration
         [ScenarioPath("/mvc/view")]
         public bool MvcViews { get; set; }
 
-        //[ScenarioPath("/mvc/db/raw")]
-        //public bool MvcDbSingleQueryRaw { get; set; }
+        [ScenarioPath("/mvc/db/raw")]
+        public bool MvcDbSingleQueryRaw { get; set; }
+
+        [ScenarioPath("/mvc/db/dapper")]
+        public bool MvcDbSingleQueryDapper { get; set; }
+
+        [ScenarioPath("/mvc/db/ef")]
+        public bool MvcDbSingleQueryEf { get; set; }
+
+        [ScenarioPath("/mvc/queries/raw")]
+        public bool MvcDbMultiQueryRaw { get; set; }
 
-        //[ScenarioPath("/mvc/db/dapper")]
-        //public bool MvcDbSingleQueryDapper { get; set; }
+        [ScenarioPath("/mvc/queries/dapper")]
+        public bool MvcDbMultiQueryDapper { get; set; }
 
-        //[ScenarioPath("/mvc/db/ef")]
-        //public bool MvcDbSingleQueryEf { get; set; }
+        [ScenarioPath("/mvc/queries/ef")]
+        public bool MvcDbMultiQueryEf { get; set; }
 
-        //[ScenarioPath("/mvc/queries/raw")]
-        //public bool MvcDbMultiQueryRaw { get; set; }
+        [ScenarioPath("/mvc/updates/raw")]
+        public bool MvcDbMultiUpdateRaw { get; set; }
 
-        //[ScenarioPath("/mvc/queries/dapper")]
-        //public bool MvcDbMultiQueryDapper { get; set; }
+        [ScenarioPath("/mvc/updates/dapper")]
+        public bool MvcDbMultiUpdateDapper { get; set; }
 
-        //[ScenarioPath("/mvc/queries/ef")]
-        //public bool MvcDbMultiQueryEf { get; set; }
+        [ScenarioPath("/mvc/updates/ef")]
+        public bool MvcDbMultiUpdateEf { get; set; }
 
         [ScenarioPath("/mvc/fortunes/raw")]
         public bool MvcDbFortunesRaw { get; set; }

+ 11 - 51
frameworks/CSharp/aspnetcore/Benchmarks/Controllers/FortunesController.cs

@@ -8,68 +8,28 @@ using Microsoft.Extensions.DependencyInjection;
 
 namespace Benchmarks.Controllers
 {
-    [Route("mvc")]
+    [Route("mvc/fortunes")]
     public class FortunesController : Controller
     {
-        private RawDb _rawDb;
-        private DapperDb _dapperDb;
-        private EfDb _efDb;
-
-        private RawDb RawDb
-        {
-            get
-            {
-                if (_rawDb == null)
-                {
-                    _rawDb = HttpContext.RequestServices.GetRequiredService<RawDb>();
-                }
-
-                return _rawDb;
-            }
-        }
-
-        private DapperDb DapperDb
-        {
-            get
-            {
-                if (_dapperDb == null)
-                {
-                    _dapperDb = HttpContext.RequestServices.GetRequiredService<DapperDb>();
-                }
-
-                return _dapperDb;
-            }
-        }
-
-        private EfDb EfDb
-        {
-            get
-            {
-                if (_efDb == null)
-                {
-                    _efDb = HttpContext.RequestServices.GetRequiredService<EfDb>();
-                }
-
-                return _efDb;
-            }
-        }
-
-        [HttpGet("fortunes/raw")]
+        [HttpGet("raw")]
         public async Task<IActionResult> Raw()
-        {
-            return View("Fortunes", await RawDb.LoadFortunesRows());
+        {   
+            var db = HttpContext.RequestServices.GetRequiredService<RawDb>();
+            return View("Fortunes", await db.LoadFortunesRows());
         }
 
-        [HttpGet("fortunes/dapper")]
+        [HttpGet("dapper")]
         public async Task<IActionResult> Dapper()
         {
-            return View("Fortunes", await DapperDb.LoadFortunesRows());
+            var db = HttpContext.RequestServices.GetRequiredService<DapperDb>();
+            return View("Fortunes", await db.LoadFortunesRows());
         }
 
-        [HttpGet("fortunes/ef")]
+        [HttpGet("ef")]
         public async Task<IActionResult> Ef()
         {
-            return View("Fortunes", await EfDb.LoadFortunesRows());
+            var db = HttpContext.RequestServices.GetRequiredService<EfDb>();
+            return View("Fortunes", await db.LoadFortunesRows());
         }
     }
 }

+ 42 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Controllers/MultipleQueriesController.cs

@@ -0,0 +1,42 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Threading.Tasks;
+using Benchmarks.Data;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Benchmarks.Controllers
+{
+    [Route("mvc/queries")]
+    public class MultipleQueriesController : Controller
+    {
+        [HttpGet("raw")]
+        [Produces("application/json")]
+        public Task<World[]> Raw(int queries = 1)
+        {
+            return ExecuteQuery<RawDb>(queries);
+        }
+
+        [HttpGet("dapper")]
+        [Produces("application/json")]
+        public Task<World[]> Dapper(int queries = 1)
+        {
+            return ExecuteQuery<DapperDb>(queries);
+        }
+
+        [HttpGet("ef")]
+        [Produces("application/json")]
+        public Task<World[]> Ef(int queries = 1)
+        {
+            return ExecuteQuery<EfDb>(queries);
+        }
+
+        private Task<World[]> ExecuteQuery<T>(int queries) where T : IDb
+        {
+            queries = queries < 1 ? 1 : queries > 500 ? 500 : queries;
+            var db = HttpContext.RequestServices.GetRequiredService<T>();
+            return db.LoadMultipleQueriesRows(queries);
+        }
+    }
+}

+ 42 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Controllers/MultipleUpdatesController.cs

@@ -0,0 +1,42 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Threading.Tasks;
+using Benchmarks.Data;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Benchmarks.Controllers
+{
+    [Route("mvc/updates")]
+    public class MultipleUpdatesController : Controller
+    {
+        [HttpGet("raw")]
+        [Produces("application/json")]
+        public Task<World[]> Raw(int queries = 1)
+        {
+            return ExecuteQuery<RawDb>(queries);
+        }
+
+        [HttpGet("dapper")]
+        [Produces("application/json")]
+        public Task<World[]> Dapper(int queries = 1)
+        {
+            return ExecuteQuery<DapperDb>(queries);
+        }
+
+        [HttpGet("ef")]
+        [Produces("application/json")]
+        public Task<World[]> Ef(int queries = 1)
+        {
+            return ExecuteQuery<EfDb>(queries);
+        }
+
+        private Task<World[]> ExecuteQuery<T>(int queries) where T : IDb
+        {
+            queries = queries < 1 ? 1 : queries > 500 ? 500 : queries;
+            var db = HttpContext.RequestServices.GetRequiredService<T>();
+            return db.LoadMultipleUpdatesRows(queries);
+        }
+    }
+}

+ 41 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Controllers/SingleQueryController.cs

@@ -0,0 +1,41 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Threading.Tasks;
+using Benchmarks.Data;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Benchmarks.Controllers
+{
+    [Route("mvc/db")]
+    public class SingleQueryController : Controller
+    {
+        [HttpGet("raw")]
+        [Produces("application/json")]
+        public Task<World> Raw()
+        {
+            return ExecuteQuery<RawDb>();
+        }
+
+        [HttpGet("dapper")]
+        [Produces("application/json")]
+        public Task<World> Dapper()
+        {
+            return ExecuteQuery<DapperDb>();
+        }
+
+        [HttpGet("ef")]
+        [Produces("application/json")]
+        public Task<World> Ef()
+        {
+            return ExecuteQuery<EfDb>();
+        }
+
+        private Task<World> ExecuteQuery<T>() where T : IDb
+        {
+            var db = HttpContext.RequestServices.GetRequiredService<T>();
+            return db.LoadSingleQueryRow();
+        }
+    }
+}

+ 49 - 2
frameworks/CSharp/aspnetcore/Benchmarks/Data/ApplicationDbContext.cs

@@ -1,9 +1,14 @@
 // Copyright (c) .NET Foundation. All rights reserved. 
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
 
+using System.Linq;
 using Benchmarks.Configuration;
 using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.Internal;
+using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
 using Microsoft.Extensions.Options;
+using Microsoft.Extensions.DependencyInjection;
 
 namespace Benchmarks.Data
 {
@@ -20,9 +25,51 @@ namespace Benchmarks.Data
 
         public DbSet<Fortune> Fortune { get; set; }
 
+        public bool UseBatchUpdate 
+        { 
+            get
+            {
+                return _appSettings.Database != DatabaseServer.PostgreSql;
+            }
+        } 
+
         protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
         {
-            optionsBuilder.UseSqlServer(_appSettings.ConnectionString);
+            if (_appSettings.Database == DatabaseServer.PostgreSql)
+            {
+                optionsBuilder.UseNpgsql(_appSettings.ConnectionString);
+            }
+            else
+            {
+                var extension = GetOrCreateExtension(optionsBuilder);
+                extension.ConnectionString = _appSettings.ConnectionString;
+                ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
+            }
+        }
+
+        private static SqlServerOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder optionsBuilder)
+        {
+            var existing = optionsBuilder.Options.FindExtension<NoTxSqlServerOptionsExtension>();
+            return existing != null
+                ? new NoTxSqlServerOptionsExtension(existing)
+                : new NoTxSqlServerOptionsExtension();
+        }
+
+        private class NoTxSqlServerOptionsExtension : SqlServerOptionsExtension
+        {
+            public NoTxSqlServerOptionsExtension()
+            {
+            }
+
+            public NoTxSqlServerOptionsExtension(NoTxSqlServerOptionsExtension copyFrom) : base(copyFrom)
+            {
+            }
+            public override void ApplyServices(IServiceCollection services)
+            {
+                base.ApplyServices(services);
+                services.Remove(services.First((sd) => sd.ServiceType == typeof(ISqlServerConnection)));
+                services.AddScoped<ISqlServerConnection, NoTransactionSqlServerConnection>();
+            }
         }
     }
-}
+}

+ 24 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Data/BatchUpdateString.cs

@@ -0,0 +1,24 @@
+// Copyright (c) .NET Foundation. All rights reserved. 
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Benchmarks.Data
+{
+    internal class BatchUpdateString
+    {
+        public static IList<BatchUpdateString> Strings { get;} = 
+            Enumerable.Range(0, 500)
+                      .Select(i => new BatchUpdateString
+                      {
+                          Id = $"Id_{i}",
+                          Random = $"Random_{i}",
+                          UpdateQuery = $"UPDATE world SET randomnumber = @Random_{i} WHERE id = @Id_{i};"
+                      }).ToArray();
+                        
+        public string Id { get; set; }
+        public string Random { get; set; }
+        public string UpdateQuery { get; set; }
+    }
+}

+ 50 - 12
frameworks/CSharp/aspnetcore/Benchmarks/Data/DapperDb.cs

@@ -1,8 +1,11 @@
 // Copyright (c) .NET Foundation. All rights reserved. 
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
 
+using System;
 using System.Collections.Generic;
 using System.Data.Common;
+using System.Dynamic;
+using System.Text;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Dapper;
@@ -10,7 +13,7 @@ using Microsoft.Extensions.Options;
 
 namespace Benchmarks.Data
 {
-    public class DapperDb
+    public class DapperDb : IDb
     {
         private readonly IRandom _random;
         private readonly DbProviderFactory _dbProviderFactory;
@@ -30,15 +33,39 @@ namespace Benchmarks.Data
                 db.ConnectionString = _connectionString;
 
                 // Note: Don't need to open connection if only doing one thing; let dapper do it
-                return await db.QueryFirstOrDefaultAsync<World>(
-                    "SELECT [Id], [RandomNumber] FROM [World] WHERE [Id] = @Id",
-                    new { Id = _random.Next(1, 10001) });
+                return await ReadSingleRow(db);
             }
         }
 
+        async Task<World> ReadSingleRow(DbConnection db)
+        {
+            return await db.QueryFirstOrDefaultAsync<World>(
+                    "SELECT id, randomnumber FROM world WHERE id = @Id",
+                    new { Id = _random.Next(1, 10001) });
+        }
+
         public async Task<World[]> LoadMultipleQueriesRows(int count)
         {
-            var result = new World[count];
+            var results = new World[count];
+            using (var db = _dbProviderFactory.CreateConnection())
+            {
+                db.ConnectionString = _connectionString;
+                await db.OpenAsync();
+
+                for (int i = 0; i < count; i++)
+                {
+                    results[i] = await ReadSingleRow(db);
+                }
+            }
+
+            return results;
+        }
+
+        public async Task<World[]> LoadMultipleUpdatesRows(int count)
+        {
+            var results = new World[count];
+            IDictionary<string, object> parameters = new ExpandoObject();
+            var updateCommand = new StringBuilder(count);
 
             using (var db = _dbProviderFactory.CreateConnection())
             {
@@ -47,15 +74,26 @@ namespace Benchmarks.Data
 
                 for (int i = 0; i < count; i++)
                 {
-                    result[i] = await db.QueryFirstOrDefaultAsync<World>(
-                        "SELECT [Id], [RandomNumber] FROM [World] WHERE [Id] = @Id",
-                        new { Id = _random.Next(1, 10001) });
+                    results[i] = await ReadSingleRow(db);
+                }
+
+                // postgres has problems with deadlocks when these aren't sorted
+                Array.Sort<World>(results, (a, b) => a.Id.CompareTo(b.Id));
+
+                for (int i = 0; i < count; i++)
+                {
+                    var randomNumber = _random.Next(1, 10001);
+                    parameters[BatchUpdateString.Strings[i].Random] = randomNumber;
+                    parameters[BatchUpdateString.Strings[i].Id] = results[i].Id;
+
+                    results[i].RandomNumber = randomNumber;
+                    updateCommand.Append(BatchUpdateString.Strings[i].UpdateQuery);
                 }
 
-                db.Close();
+                await db.ExecuteAsync(updateCommand.ToString(), parameters);
             }
 
-            return result;
+            return results;
         }
 
         public async Task<IEnumerable<Fortune>> LoadFortunesRows()
@@ -67,7 +105,7 @@ namespace Benchmarks.Data
                 db.ConnectionString = _connectionString;
 
                 // Note: don't need to open connection if only doing one thing; let dapper do it
-                result = (await db.QueryAsync<Fortune>("SELECT [Id], [Message] FROM [Fortune]")).AsList();
+                result = (await db.QueryAsync<Fortune>("SELECT id, message FROM fortune")).AsList();
             }
 
             result.Add(new Fortune { Message = "Additional fortune added at request time." });
@@ -76,4 +114,4 @@ namespace Benchmarks.Data
             return result;
         }
     }
-}
+}

+ 27 - 3
frameworks/CSharp/aspnetcore/Benchmarks/Data/EfDb.cs

@@ -7,7 +7,7 @@ using Microsoft.EntityFrameworkCore;
 
 namespace Benchmarks.Data
 {
-    public class EfDb
+    public class EfDb : IDb
     {
         private readonly IRandom _random;
         private readonly ApplicationDbContext _dbContext;
@@ -22,7 +22,6 @@ namespace Benchmarks.Data
         public Task<World> LoadSingleQueryRow()
         {
             var id = _random.Next(1, 10001);
-            
             return _dbContext.World.FirstAsync(w => w.Id == id);
         }
 
@@ -39,6 +38,31 @@ namespace Benchmarks.Data
             return result;
         }
 
+        public async Task<World[]> LoadMultipleUpdatesRows(int count)
+        {
+            var results = new World[count];
+
+            for (int i = 0; i < count; i++)
+            {
+                var id = _random.Next(1, 10001);
+                var result = await _dbContext.World.AsTracking().FirstAsync(w => w.Id == id);
+
+                result.RandomNumber = _random.Next(1, 10001);
+                results[i] = result;
+                if(!_dbContext.UseBatchUpdate)
+                {
+                    await _dbContext.SaveChangesAsync();
+                }
+            }
+            
+            if(_dbContext.UseBatchUpdate)
+            {
+                await _dbContext.SaveChangesAsync();
+            }
+
+            return results;
+        }
+
         public async Task<IEnumerable<Fortune>> LoadFortunesRows()
         {
             var result = await _dbContext.Fortune.ToListAsync();
@@ -49,4 +73,4 @@ namespace Benchmarks.Data
             return result;
         }
     }
-}
+}

+ 4 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Data/Fortune.cs

@@ -3,13 +3,17 @@
 
 using System;
 using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
 
 namespace Benchmarks.Data
 {
+    [Table("fortune")]
     public class Fortune : IComparable<Fortune>, IComparable
     {
+        [Column("id")]
         public int Id { get; set; }
 
+        [Column("message")]
         [StringLength(2048)]
         public string Message { get; set; }
         

+ 19 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Data/IDb.cs

@@ -0,0 +1,19 @@
+// Copyright (c) .NET Foundation. All rights reserved. 
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Benchmarks.Data
+{
+    public interface IDb
+    {
+        Task<World> LoadSingleQueryRow();
+
+        Task<World[]> LoadMultipleQueriesRows(int count);
+
+        Task<World[]> LoadMultipleUpdatesRows(int count);
+
+        Task<IEnumerable<Fortune>> LoadFortunesRows();
+    }
+}

+ 43 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Data/NoTransactionSqlServerConnection.cs

@@ -0,0 +1,43 @@
+// Copyright (c) .NET Foundation. All rights reserved. 
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
+
+using System.Data;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Storage.Internal;
+using Microsoft.Extensions.Logging;
+
+namespace Benchmarks.Data
+{
+    class NoTransactionSqlServerConnection : SqlServerConnection
+    {
+        public NoTransactionSqlServerConnection(IDbContextOptions options, ILogger<SqlServerConnection> logger)
+            : base(options, logger)
+        {
+        }
+
+        public override Task<IDbContextTransaction> BeginTransactionAsync(
+            IsolationLevel isolationLevel, CancellationToken cancellationToken = new CancellationToken())
+            => Task.FromResult<IDbContextTransaction>(new FakeTransaction());
+
+        public override IDbContextTransaction BeginTransaction(IsolationLevel isolationLevel) 
+            => new FakeTransaction();
+
+        private class FakeTransaction : IDbContextTransaction
+        {
+            public void Dispose()
+            {
+            }
+
+            public void Commit()
+            {
+            }
+
+            public void Rollback()
+            {
+            }
+        }
+    }
+}

+ 6 - 3
frameworks/CSharp/aspnetcore/Benchmarks/Data/Random.cs

@@ -2,16 +2,19 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
 
 using System;
+using System.Threading;
 
 namespace Benchmarks.Data
 {
     public class DefaultRandom : IRandom
     {
-        private readonly Random _random = new Random();
+        private static int nextSeed = 0;
+        // Random isn't thread safe
+        private static readonly ThreadLocal<Random> _random = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref nextSeed)));
 
         public int Next(int minValue, int maxValue)
         {
-            return _random.Next(minValue, maxValue);
+            return _random.Value.Next(minValue, maxValue);
         }
     }
-}
+}

+ 89 - 39
frameworks/CSharp/aspnetcore/Benchmarks/Data/RawDb.cs

@@ -1,21 +1,23 @@
 // Copyright (c) .NET Foundation. All rights reserved. 
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
 
+using System;
 using System.Collections.Generic;
 using System.Data;
 using System.Data.Common;
+using System.Text;
 using System.Threading.Tasks;
 using Benchmarks.Configuration;
 using Microsoft.Extensions.Options;
 
 namespace Benchmarks.Data
 {
-    public class RawDb
+    public class RawDb : IDb
     {
         private readonly IRandom _random;
         private readonly DbProviderFactory _dbProviderFactory;
         private readonly string _connectionString;
-
+        
         public RawDb(IRandom random, DbProviderFactory dbProviderFactory, IOptions<AppSettings> appSettings)
         {
             _random = random;
@@ -26,66 +28,111 @@ namespace Benchmarks.Data
         public async Task<World> LoadSingleQueryRow()
         {
             using (var db = _dbProviderFactory.CreateConnection())
-            using (var cmd = db.CreateCommand())
+            using (var cmd = CreateReadCommand(db))
             {
-                cmd.CommandText = "SELECT [Id], [RandomNumber] FROM [World] WHERE [Id] = @Id";
-                var id = cmd.CreateParameter();
-                id.ParameterName = "@Id";
-                id.DbType = DbType.Int32;
-                id.Value = _random.Next(1, 10001);
-                cmd.Parameters.Add(id);
-
                 db.ConnectionString = _connectionString;
                 await db.OpenAsync();
 
-                using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection))
-                {
-                    await rdr.ReadAsync();
+                return await ReadSingleRow(db, cmd);
+            }
+        }
+        
+        async Task<World> ReadSingleRow(DbConnection connection, DbCommand cmd)
+        {
+            // Prepared statements improve PostgreSQL performance by 10-15%
+            cmd.Prepare();
 
-                    return new World
-                    {
-                        Id = rdr.GetInt32(0),
-                        RandomNumber = rdr.GetInt32(1)
-                    };
-                }
+            using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.SingleRow))
+            {
+                await rdr.ReadAsync();
+
+                return new World
+                {
+                    Id = rdr.GetInt32(0),
+                    RandomNumber = rdr.GetInt32(1)
+                };
             }
         }
 
+        DbCommand CreateReadCommand(DbConnection connection)
+        {
+            var cmd = connection.CreateCommand();
+            cmd.CommandText = "SELECT id, randomnumber FROM world WHERE id = @Id";
+            var id = cmd.CreateParameter();
+            id.ParameterName = "@Id";
+            id.DbType = DbType.Int32;
+            id.Value = _random.Next(1, 10001);
+            cmd.Parameters.Add(id);
+
+            return cmd;
+        }
+
         public async Task<World[]> LoadMultipleQueriesRows(int count)
         {
             var result = new World[count];
 
             using (var db = _dbProviderFactory.CreateConnection())
-            using (var cmd = db.CreateCommand())
+            using (var cmd = CreateReadCommand(db))
             {
                 db.ConnectionString = _connectionString;
                 await db.OpenAsync();
+                for (int i = 0; i < count; i++)
+                {
+                    result[i] = await ReadSingleRow(db, cmd);
+                    cmd.Parameters["@Id"].Value = _random.Next(1, 10001);
+                }
+            }
+
+            return result;
+        }
+
+        public async Task<World[]> LoadMultipleUpdatesRows(int count)
+        {
+            var results = new World[count];
+           
+            var updateCommand = new StringBuilder(count);
 
-                cmd.CommandText = "SELECT [Id], [RandomNumber] FROM [World] WHERE [Id] = @Id";
-                var id = cmd.CreateParameter();
-                id.ParameterName = "@Id";
-                id.DbType = DbType.Int32;
-                cmd.Parameters.Add(id);
+            using (var db = _dbProviderFactory.CreateConnection())
+            using (var updateCmd = db.CreateCommand())
+            using (var queryCmd = CreateReadCommand(db))
+            {
+                db.ConnectionString = _connectionString;
+                await db.OpenAsync();
 
                 for (int i = 0; i < count; i++)
                 {
-                    id.Value = _random.Next(1, 10001);
-                    using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.SingleRow))
-                    {
-                        await rdr.ReadAsync();
+                    results[i] = await ReadSingleRow(db, queryCmd);
+                    queryCmd.Parameters["@Id"].Value = _random.Next(1, 10001);
+                }
 
-                        result[i] = new World
-                        {
-                            Id = rdr.GetInt32(0),
-                            RandomNumber = rdr.GetInt32(1)
-                        };
-                    }
+                // postgres has problems with deadlocks when these aren't sorted
+                Array.Sort<World>(results, (a, b) => a.Id.CompareTo(b.Id));
+
+                for(int i = 0; i < count; i++)
+                {
+                    var id = updateCmd.CreateParameter();
+                    id.ParameterName = BatchUpdateString.Strings[i].Id;
+                    id.DbType = DbType.Int32;
+                    updateCmd.Parameters.Add(id);
+
+                    var random = updateCmd.CreateParameter();
+                    random.ParameterName = BatchUpdateString.Strings[i].Random;
+                    id.DbType = DbType.Int32;
+                    updateCmd.Parameters.Add(random);
+
+                    var randomNumber = _random.Next(1, 10001);
+                    id.Value = results[i].Id;
+                    random.Value = randomNumber;
+                    results[i].RandomNumber = randomNumber;
+
+                    updateCommand.Append(BatchUpdateString.Strings[i].UpdateQuery);
                 }
 
-                db.Close();
+                updateCmd.CommandText = updateCommand.ToString();
+                await updateCmd.ExecuteNonQueryAsync();
             }
 
-            return result;
+            return results;
         }
 
         public async Task<IEnumerable<Fortune>> LoadFortunesRows()
@@ -95,11 +142,14 @@ namespace Benchmarks.Data
             using (var db = _dbProviderFactory.CreateConnection())
             using (var cmd = db.CreateCommand())
             {
-                cmd.CommandText = "SELECT [Id], [Message] FROM [Fortune]";
+                cmd.CommandText = "SELECT id, message FROM fortune";
 
                 db.ConnectionString = _connectionString;
                 await db.OpenAsync();
 
+                // Prepared statements improve PostgreSQL performance by 10-15%
+                cmd.Prepare();
+
                 using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection))
                 {
                     while (await rdr.ReadAsync())
@@ -119,4 +169,4 @@ namespace Benchmarks.Data
             return result;
         }
     }
-}
+}

+ 5 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Data/World.cs

@@ -1,12 +1,17 @@
 // Copyright (c) .NET Foundation. All rights reserved. 
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
 
+using System.ComponentModel.DataAnnotations.Schema;
+
 namespace Benchmarks.Data
 {
+    [Table("world")]
     public class World
     {
+        [Column("id")] 
         public int Id { get; set; }
 
+        [Column("randomnumber")] 
         public int RandomNumber { get; set; }
     }
 }

+ 0 - 47
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/ErrorHandlerMiddleware.cs

@@ -1,47 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved. 
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
-
-using System;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http;
-
-namespace Benchmarks.Middleware
-{
-    public class ErrorHandlerMiddleware
-    {
-        private readonly RequestDelegate _next;
-
-        public ErrorHandlerMiddleware(RequestDelegate next)
-        {
-            _next = next;
-        }
-
-        public async Task Invoke(HttpContext httpContext)
-        {
-            try
-            {
-                await _next(httpContext);
-            }
-            catch (Exception ex)
-            {
-                if (!httpContext.Response.HasStarted)
-                {
-                    httpContext.Response.Clear();
-                    httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
-                    httpContext.Response.ContentType = "text/html";
-                }
-                
-                await httpContext.Response.WriteAsync($"<pre style='color:red'>{ex.ToString()}</pre>");
-            }
-        }
-    }
-
-    public static class ErrorHandlerMiddlewareExtensions
-    {
-        public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder builder)
-        {
-            return builder.UseMiddleware<ErrorHandlerMiddleware>();
-        }
-    }
-}

+ 5 - 5
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/FortunesEfMiddleware.cs

@@ -8,6 +8,7 @@ using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
 
 namespace Benchmarks.Middleware
 {
@@ -16,13 +17,11 @@ namespace Benchmarks.Middleware
         private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbFortunesEf));
 
         private readonly RequestDelegate _next;
-        private readonly EfDb _db;
         private readonly HtmlEncoder _htmlEncoder;
 
-        public FortunesEfMiddleware(RequestDelegate next, EfDb db, HtmlEncoder htmlEncoder)
+        public FortunesEfMiddleware(RequestDelegate next, HtmlEncoder htmlEncoder)
         {
             _next = next;
-            _db = db;
             _htmlEncoder = htmlEncoder;
         }
 
@@ -30,7 +29,8 @@ namespace Benchmarks.Middleware
         {
             if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
             {
-                var rows = await _db.LoadFortunesRows();
+                var db = httpContext.RequestServices.GetService<EfDb>();
+                var rows = await db.LoadFortunesRows();
 
                 await MiddlewareHelpers.RenderFortunesHtml(rows, httpContext, _htmlEncoder);
 
@@ -48,4 +48,4 @@ namespace Benchmarks.Middleware
             return builder.UseMiddleware<FortunesEfMiddleware>();
         }
     }
-}
+}

+ 14 - 5
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MiddlewareHelpers.cs

@@ -2,6 +2,8 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
 using System.Text.Encodings.Web;
 using System.Threading.Tasks;
 using Benchmarks.Data;
@@ -33,15 +35,22 @@ namespace Benchmarks.Middleware
             httpContext.Response.StatusCode = StatusCodes.Status200OK;
             httpContext.Response.ContentType = "text/html; charset=UTF-8";
 
-            await httpContext.Response.WriteAsync("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>");
-
+            var sb = new StringBuilder();
+            sb.Append("<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>");
             foreach (var item in model)
             {
-                await httpContext.Response.WriteAsync(
-                    $"<tr><td>{htmlEncoder.Encode(item.Id.ToString())}</td><td>{htmlEncoder.Encode(item.Message)}</td></tr>");
+                sb.Append("<tr><td>");
+                sb.Append(item.Id.ToString(CultureInfo.InvariantCulture));
+                sb.Append("</td><td>");
+                sb.Append(htmlEncoder.Encode(item.Message));
+                sb.Append("</td></tr>");
             }
 
-            await httpContext.Response.WriteAsync("</table></body></html>");
+            sb.Append("</table></body></html>");
+            var response = sb.ToString();
+            // fortunes includes multibyte characters so response.Length is incorrect
+            httpContext.Response.ContentLength = Encoding.UTF8.GetByteCount(response);
+            await httpContext.Response.WriteAsync(response);
         }
     }
 }

+ 5 - 5
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleQueriesEfMiddleware.cs

@@ -7,6 +7,7 @@ using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Serialization;
 
@@ -21,20 +22,19 @@ namespace Benchmarks.Middleware
         };
 
         private readonly RequestDelegate _next;
-        private readonly EfDb _db;
 
-        public MultipleQueriesEfMiddleware(RequestDelegate next, EfDb db)
+        public MultipleQueriesEfMiddleware(RequestDelegate next)
         {
             _next = next;
-            _db = db;
         }
 
         public async Task Invoke(HttpContext httpContext)
         {
             if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
             {
+                var db = httpContext.RequestServices.GetService<EfDb>();
                 var count = MiddlewareHelpers.GetMultipleQueriesQueryCount(httpContext);
-                var rows = await _db.LoadMultipleQueriesRows(count);
+                var rows = await db.LoadMultipleQueriesRows(count);
 
                 var result = JsonConvert.SerializeObject(rows, _jsonSettings);
 
@@ -58,4 +58,4 @@ namespace Benchmarks.Middleware
             return builder.UseMiddleware<MultipleQueriesEfMiddleware>();
         }
     }
-}
+}

+ 61 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesDapperMiddleware.cs

@@ -0,0 +1,61 @@
+// Copyright (c) .NET Foundation. All rights reserved. 
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
+
+using System;
+using System.Threading.Tasks;
+using Benchmarks.Configuration;
+using Benchmarks.Data;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+
+namespace Benchmarks.Middleware
+{
+    public class MultipleUpdatesDapperMiddleware
+    {
+        private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiUpdateDapper));
+        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
+        {
+            ContractResolver = new CamelCasePropertyNamesContractResolver()
+        };
+
+        private readonly RequestDelegate _next;
+        private readonly DapperDb _db;
+
+        public MultipleUpdatesDapperMiddleware(RequestDelegate next, DapperDb db)
+        {
+            _next = next;
+            _db = db;
+        }
+
+        public async Task Invoke(HttpContext httpContext)
+        {
+            if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
+            {
+                var count = MiddlewareHelpers.GetMultipleQueriesQueryCount(httpContext);
+                var rows = await _db.LoadMultipleUpdatesRows(count);
+
+                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+
+                httpContext.Response.StatusCode = StatusCodes.Status200OK;
+                httpContext.Response.ContentType = "application/json";
+                httpContext.Response.ContentLength = result.Length;
+
+                await httpContext.Response.WriteAsync(result);
+
+                return;
+            }
+
+            await _next(httpContext);
+        }
+    }
+
+    public static class MultipleUpdatesDapperMiddlewareExtensions
+    {
+        public static IApplicationBuilder UseMultipleUpdatesDapper(this IApplicationBuilder builder)
+        {
+            return builder.UseMiddleware<MultipleUpdatesDapperMiddleware>();
+        }
+    }
+}

+ 61 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesEfMiddleware.cs

@@ -0,0 +1,61 @@
+// Copyright (c) .NET Foundation. All rights reserved. 
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
+
+using System;
+using System.Threading.Tasks;
+using Benchmarks.Configuration;
+using Benchmarks.Data;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+
+namespace Benchmarks.Middleware
+{
+    public class MultipleUpdatesEfMiddleware
+    {
+        private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiUpdateEf));
+        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
+        {
+            ContractResolver = new CamelCasePropertyNamesContractResolver()
+        };
+
+        private readonly RequestDelegate _next;
+
+        public MultipleUpdatesEfMiddleware(RequestDelegate next)
+        {
+            _next = next;
+        }
+
+        public async Task Invoke(HttpContext httpContext)
+        {
+            if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
+            {
+                var db = httpContext.RequestServices.GetService<EfDb>();
+                var count = MiddlewareHelpers.GetMultipleQueriesQueryCount(httpContext);
+                var rows = await db.LoadMultipleUpdatesRows(count);
+
+                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+
+                httpContext.Response.StatusCode = StatusCodes.Status200OK;
+                httpContext.Response.ContentType = "application/json";
+                httpContext.Response.ContentLength = result.Length;
+
+                await httpContext.Response.WriteAsync(result);
+
+                return;
+            }
+
+            await _next(httpContext);
+        }
+    }
+
+    public static class MultipleUpdatesEfMiddlewareExtensions
+    {
+        public static IApplicationBuilder UseMultipleUpdatesEf(this IApplicationBuilder builder)
+        {
+            return builder.UseMiddleware<MultipleUpdatesEfMiddleware>();
+        }
+    }
+}

+ 61 - 0
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/MultipleUpdatesRawMiddleware.cs

@@ -0,0 +1,61 @@
+// Copyright (c) .NET Foundation. All rights reserved. 
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 
+
+using System;
+using System.Threading.Tasks;
+using Benchmarks.Configuration;
+using Benchmarks.Data;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+
+namespace Benchmarks.Middleware
+{
+    public class MultipleUpdatesRawMiddleware
+    {
+        private static readonly PathString _path = new PathString(Scenarios.GetPath(s => s.DbMultiUpdateRaw));
+        private static readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
+        {
+            ContractResolver = new CamelCasePropertyNamesContractResolver()
+        };
+
+        private readonly RequestDelegate _next;
+        private readonly RawDb _db;
+
+        public MultipleUpdatesRawMiddleware(RequestDelegate next, RawDb db)
+        {
+            _next = next;
+            _db = db;
+        }
+
+        public async Task Invoke(HttpContext httpContext)
+        {
+            if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
+            {
+                var count = MiddlewareHelpers.GetMultipleQueriesQueryCount(httpContext);
+                var rows = await _db.LoadMultipleUpdatesRows(count);
+
+                var result = JsonConvert.SerializeObject(rows, _jsonSettings);
+
+                httpContext.Response.StatusCode = StatusCodes.Status200OK;
+                httpContext.Response.ContentType = "application/json";
+                httpContext.Response.ContentLength = result.Length;
+
+                await httpContext.Response.WriteAsync(result);
+
+                return;
+            }
+
+            await _next(httpContext);
+        }
+    }
+
+    public static class MultipleUpdatesRawMiddlewareExtensions
+    {
+        public static IApplicationBuilder UseMultipleUpdatesRaw(this IApplicationBuilder builder)
+        {
+            return builder.UseMiddleware<MultipleUpdatesRawMiddleware>();
+        }
+    }
+}

+ 5 - 5
frameworks/CSharp/aspnetcore/Benchmarks/Middleware/SingleQueryEfMiddleware.cs

@@ -7,6 +7,7 @@ using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Serialization;
 
@@ -21,19 +22,18 @@ namespace Benchmarks.Middleware
         };
 
         private readonly RequestDelegate _next;
-        private readonly EfDb _db;
 
-        public SingleQueryEfMiddleware(RequestDelegate next, EfDb db)
+        public SingleQueryEfMiddleware(RequestDelegate next)
         {
             _next = next;
-            _db = db;
         }
 
         public async Task Invoke(HttpContext httpContext)
         {
             if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
             {
-                var row = await _db.LoadSingleQueryRow();
+                var db = httpContext.RequestServices.GetService<EfDb>();
+                var row = await db.LoadSingleQueryRow();
                 var result = JsonConvert.SerializeObject(row, _jsonSettings);
 
                 httpContext.Response.StatusCode = StatusCodes.Status200OK;
@@ -56,4 +56,4 @@ namespace Benchmarks.Middleware
             return builder.UseMiddleware<SingleQueryEfMiddleware>();
         }
     }
-}
+}

+ 2 - 2
frameworks/CSharp/aspnetcore/Benchmarks/NuGet.Config

@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <packageSources>
     <clear />
-    <add key="AspNetVNext" value="https://dotnet.myget.org/F/aspnet1/api/v3/index.json" />
+    <add key="Npgsql" value="https://www.myget.org/F/npgsql-unstable/api/v3/index.json" />
     <add key="NuGet" value="https://api.nuget.org/v3/index.json" />
   </packageSources>
 </configuration>

+ 41 - 8
frameworks/CSharp/aspnetcore/Benchmarks/Startup.cs

@@ -4,6 +4,8 @@
 using System;
 using System.Data.Common;
 using System.Data.SqlClient;
+using System.Text.Encodings.Web;
+using System.Text.Unicode;
 using Benchmarks.Configuration;
 using Benchmarks.Data;
 using Benchmarks.Middleware;
@@ -11,7 +13,9 @@ using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
 using Microsoft.Extensions.PlatformAbstractions;
+using Npgsql;
 
 namespace Benchmarks
 {
@@ -49,11 +53,21 @@ namespace Benchmarks
             services.AddSingleton<ApplicationDbSeeder>();
             services.AddEntityFrameworkSqlServer()
                 .AddDbContext<ApplicationDbContext>();
-
+            
             if (Scenarios.Any("Raw") || Scenarios.Any("Dapper"))
             {
-                // TODO: Add support for plugging in different DbProviderFactory implementations via configuration
-                services.AddSingleton<DbProviderFactory>(SqlClientFactory.Instance);
+                services.AddSingleton<DbProviderFactory>((provider) => {
+                    var settings = provider.GetRequiredService<IOptions<AppSettings>>().Value;
+
+                    if (settings.Database == DatabaseServer.PostgreSql)
+                    {
+                        return NpgsqlFactory.Instance;
+                    }
+                    else
+                    {
+                        return SqlClientFactory.Instance;
+                    }
+                });
             }
 
             if (Scenarios.Any("Ef"))
@@ -73,7 +87,12 @@ namespace Benchmarks
 
             if (Scenarios.Any("Fortunes"))
             {
-                services.AddWebEncoders();
+                var settings = new TextEncoderSettings(UnicodeRanges.BasicLatin, UnicodeRanges.Katakana, UnicodeRanges.Hiragana);
+                settings.AllowCharacter('\u2014');  // allow EM DASH through
+                services.AddWebEncoders((options) =>
+                {
+                    options.TextEncoderSettings = settings;
+                });
             }
 
             if (Scenarios.Any("Mvc"))
@@ -83,7 +102,7 @@ namespace Benchmarks
                     //.AddApplicationPart(typeof(Startup).GetTypeInfo().Assembly)
                     .AddControllersAsServices();
 
-                if (Scenarios.MvcJson)
+                if (Scenarios.MvcJson || Scenarios.Any("MvcDbSingle") || Scenarios.Any("MvcDbMulti"))
                 {
                     mvcBuilder.AddJsonFormatters();
                 }
@@ -99,8 +118,6 @@ namespace Benchmarks
 
         public void Configure(IApplicationBuilder app, ApplicationDbSeeder dbSeeder, ApplicationDbContext dbContext)
         {
-            app.UseErrorHandler();
-
             if (Scenarios.Plaintext)
             {
                 app.UsePlainText();
@@ -143,6 +160,22 @@ namespace Benchmarks
                 app.UseMultipleQueriesEf();
             }
 
+            // Multiple update endpoints
+            if (Scenarios.DbMultiUpdateRaw)
+            {
+                app.UseMultipleUpdatesRaw();
+            }
+
+            if (Scenarios.DbMultiUpdateDapper)
+            {
+                app.UseMultipleUpdatesDapper();
+            }
+
+            if (Scenarios.DbMultiUpdateEf)
+            {
+                app.UseMultipleUpdatesEf();
+            }
+
             // Fortunes endpoints
             if (Scenarios.DbFortunesRaw)
             {
@@ -182,4 +215,4 @@ namespace Benchmarks
             app.RunDebugInfoPage();
         }
     }
-}
+}

+ 0 - 3
frameworks/CSharp/aspnetcore/Benchmarks/appsettings.json

@@ -1,3 +0,0 @@
-{
-  "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-Benchmarks;Trusted_Connection=True;MultipleActiveResultSets=true"
-}

+ 4 - 0
frameworks/CSharp/aspnetcore/Benchmarks/appsettings.postgresql.json

@@ -0,0 +1,4 @@
+{
+  "ConnectionString": "Server={db_server_placeholder};Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=1024;NoResetOnClose=true;PersistPrepared=true",
+  "Database": "postgresql"
+}

+ 21 - 10
frameworks/CSharp/aspnetcore/Benchmarks/project.json

@@ -1,8 +1,15 @@
 {
   "version": "1.0.0-*",
-  "compilationOptions": {
+  "buildOptions": {
     "emitEntryPoint": true,
-    "preserveCompilationContext": true
+    "preserveCompilationContext": true,
+    "copyToOutput": {
+      "include": [
+        "appsettings.json",
+        "wwwroot",
+        "Views"
+      ]
+    }
   },
   "dependencies": {
     "Dapper": "1.50.0-*",
@@ -18,7 +25,9 @@
     "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0-*",
     "Microsoft.Extensions.Configuration.Json": "1.0.0-*",
     "Microsoft.Extensions.Configuration.CommandLine": "1.0.0-*",
-    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-*"
+    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-*",
+    "Npgsql": "3.2.0-*",
+    "Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.2-*" 
   },
   "frameworks": {
     "netcoreapp1.0": {
@@ -28,7 +37,7 @@
           "version": "1.0.0-*",
           "type": "platform"
         },
-        "System.Runtime.Serialization.Primitives": "4.1.0-*"
+        "System.Runtime.Serialization.Primitives": "4.1.1-*"
       }
     },
     "net451": { }
@@ -42,14 +51,16 @@
       ]
     }
   },
-  "content": [
-    "appsettings.json",
-    "wwwroot",
-    "Views"
-  ],
+  "publishOptions": {
+    "include": [
+      "appsettings.json",
+      "wwwroot",
+      "Views"
+    ]
+  },
   "runtimeOptions": {
     "configProperties": {
       "System.GC.Server": true
     }
   }
-}
+}

+ 185 - 10
frameworks/CSharp/aspnetcore/benchmark_config.json

@@ -2,8 +2,7 @@
   "framework": "aspnetcore",
   "tests": [{
     "default": {
-      "setup_file": "setup",
-      "json_url": "/json",
+      "setup_file": "setup-plaintext",
       "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
@@ -11,18 +10,104 @@
       "database": "None",
       "framework": "aspnetcore",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
       "platform": "NET",
-      "webserver": "Kestrel",
+      "flavor": "CoreCLR",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "aspnetcore-linux",
       "notes": "",
       "versus": ""
     },
+    "middleware-json": {
+      "setup_file": "setup-json",
+      "json_url": "/json",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "None",
+      "framework": "aspnetcore",
+      "language": "C#",
+      "orm": "Raw",
+      "platform": "NET",
+      "flavor": "CoreCLR",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aspnetcore-linux",
+      "notes": "",
+      "versus": ""
+    },
+    "middleware-raw": {
+      "setup_file": "setup-raw",
+      "db_url": "/db/raw",
+      "query_url": "/queries/raw?queries=",
+      "update_url": "/updates/raw?queries=",
+      "fortune_url": "/fortunes/raw",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "Postgres",
+      "framework": "aspnetcore",
+      "language": "C#",
+      "orm": "Raw",
+      "platform": "NET",
+      "flavor": "CoreCLR",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aspnetcore-middleware-raw",
+      "notes": "",
+      "versus": ""
+    },
+    "middleware-ef": {
+      "setup_file": "setup-ef",
+      "db_url": "/db/ef",
+      "query_url": "/queries/ef?queries=",
+      "update_url": "/updates/ef?queries=",
+      "fortune_url": "/fortunes/ef",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "Postgres",
+      "framework": "aspnetcore",
+      "language": "C#",
+      "orm": "Full",
+      "platform": "NET",
+      "flavor": "CoreCLR",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aspnetcore-middleware-ef",
+      "notes": "",
+      "versus": ""
+    },
+    "middleware-dapper": {
+      "setup_file": "setup-dapper",
+      "db_url": "/db/dapper",
+      "query_url": "/queries/dapper?queries=",
+      "update_url": "/updates/dapper?queries=",
+      "fortune_url": "/fortunes/dapper",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "Postgres",
+      "framework": "aspnetcore",
+      "language": "C#",
+      "orm": "Micro",
+      "platform": "NET",
+      "flavor": "CoreCLR",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aspnetcore-middleware-dapper",
+      "notes": "",
+      "versus": ""
+    },
     "mvc-linux": {
-      "setup_file": "setup-mvc",
-      "json_url": "/mvc/json",
+      "setup_file": "setup-plaintext",
       "plaintext_url": "/mvc/plaintext",
       "port": 8080,
       "approach": "Realistic",
@@ -32,13 +117,99 @@
       "language": "C#",
       "orm": "Raw",
       "platform": "NET",
-      "webserver": "Kestrel",
+      "flavor": "CoreCLR",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "aspnetcore-mvc-linux",
       "notes": "",
       "versus": ""
     },
+    "mvc-linux-json": {
+      "setup_file": "setup-json",
+      "json_url": "/mvc/json",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "None",
+      "framework": "aspnetcore",
+      "language": "C#",
+      "orm": "Raw",
+      "platform": "NET",
+      "flavor": "CoreCLR",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aspnetcore-mvc-linux",
+      "notes": "",
+      "versus": ""
+    },
+    "mvc-raw": {
+      "setup_file": "setup-raw",
+      "db_url": "/mvc/db/raw",
+      "query_url": "/mvc/queries/raw?queries=",
+      "update_url": "/mvc/updates/raw?queries=",
+      "fortune_url": "/mvc/fortunes/raw",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "Postgres",
+      "framework": "aspnetcore",
+      "language": "C#",
+      "orm": "Raw",
+      "platform": "NET",
+      "flavor": "CoreCLR",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aspnetcore-mvc-raw",
+      "notes": "",
+      "versus": ""
+    },
+    "mvc-ef": {
+      "setup_file": "setup-ef",
+      "db_url": "/mvc/db/ef",
+      "query_url": "/mvc/queries/ef?queries=",
+      "update_url": "/mvc/updates/ef?queries=",
+      "fortune_url": "/mvc/fortunes/ef",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "Postgres",
+      "framework": "aspnetcore",
+      "language": "C#",
+      "orm": "Full",
+      "platform": "NET",
+      "flavor": "CoreCLR",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aspnetcore-mvc-ef",
+      "notes": "",
+      "versus": ""
+    },
+    "mvc-dapper": {
+      "setup_file": "setup-dapper",
+      "db_url": "/mvc/db/dapper",
+      "query_url": "/mvc/queries/dapper?queries=",
+      "update_url": "/mvc/updates/dapper?queries=",
+      "fortune_url": "/mvc/fortunes/dapper",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Fullstack",
+      "database": "Postgres",
+      "framework": "aspnetcore",
+      "language": "C#",
+      "orm": "Micro",
+      "platform": "NET",
+      "flavor": "CoreCLR",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "aspnetcore-mvc-dapper",
+      "notes": "",
+      "versus": ""
+    },
     "win": {
       "setup_file": "setup-windows",
       "json_url": "/json",
@@ -51,7 +222,8 @@
       "language": "C#",
       "orm": "Raw",
       "platform": "NET",
-      "webserver": "Kestrel",
+      "flavor": "CoreCLR",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "aspnetcore-win",
@@ -70,7 +242,8 @@
       "language": "C#",
       "orm": "Raw",
       "platform": "NET",
-      "webserver": "Kestrel",
+      "flavor": "CoreCLR",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "aspnetcore-mvc-win",
@@ -89,7 +262,8 @@
       "language": "C#",
       "orm": "Raw",
       "platform": "NET",
-      "webserver": "WebListener",
+      "flavor": "CoreCLR",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "aspnetcore-weblistener",
@@ -108,7 +282,8 @@
       "language": "C#",
       "orm": "Raw",
       "platform": "NET",
-      "webserver": "WebListener",
+      "flavor": "CoreCLR",
+      "webserver": "None",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "aspnetcore-mvc-weblistener",

+ 10 - 2
frameworks/CSharp/aspnetcore/run-linux.sh

@@ -1,8 +1,16 @@
 #!/bin/bash
 fw_depends mono dotnetcore
-sudo apt-get install unzip libunwind8 -y
+
+threadCount=$2
+if [ "$threadCount" -lt "1" ]
+then
+    threadCount=1
+fi
 
 cd Benchmarks
+cp appsettings.postgresql.json appsettings.json
+sed -i 's|{db_server_placeholder}|'"${DBHOST}"'|g' appsettings.json
 dotnet restore
 dotnet build -c Release -f netcoreapp1.0
-dotnet run -c Release server.urls=http://*:8080 scenarios=$1 server=kestrel threadCount=1 NonInteractive=true &
+
+dotnet run -c Release server.urls=http://*:8080 scenarios=$1 server=kestrel threadCount=$threadCount NonInteractive=true &

+ 3 - 0
frameworks/CSharp/aspnetcore/setup-dapper.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+source run-linux.sh dapper $(($(nproc)/2))

+ 3 - 0
frameworks/CSharp/aspnetcore/setup-ef.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+source run-linux.sh ef $(($(nproc)/2))

+ 3 - 0
frameworks/CSharp/aspnetcore/setup-json.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+source run-linux.sh json $(nproc)

+ 0 - 3
frameworks/CSharp/aspnetcore/setup-mvc.sh

@@ -1,3 +0,0 @@
-#!/bin/bash
-
-source run-linux.sh mvcjson,mvcplain

+ 3 - 0
frameworks/CSharp/aspnetcore/setup-plaintext.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+source run-linux.sh plaintext $(($(nproc)*3/10))

+ 3 - 0
frameworks/CSharp/aspnetcore/setup-raw.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+source run-linux.sh raw $(($(nproc)/2))

+ 0 - 3
frameworks/CSharp/aspnetcore/setup.sh

@@ -1,3 +0,0 @@
-#!/bin/bash
-
-source run-linux.sh [default]

+ 3 - 2
frameworks/CSharp/evhttp-sharp/benchmark_config.json

@@ -11,14 +11,15 @@
       "database": "None",
       "framework": "evhttp-sharp",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "evhttp-sharp",
       "notes": "",
-      "versus": ""
+      "versus": "evhttp-sharp"
     }
   }]
 }

+ 6 - 4
frameworks/CSharp/nancy/benchmark_config.json

@@ -13,14 +13,15 @@
       "database": "MySQL",
       "framework": "nancy",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": ".NET",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "nancy",
       "notes": "",
-      "versus": ""
+      "versus": "nancy"
     },
     "mono": {
       "setup_file": "setup_nginx",
@@ -34,14 +35,15 @@
       "database": "MySQL",
       "framework": "nancy",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": ".NET",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "nancy",
       "notes": "",
-      "versus": ""
+      "versus": "nancy"
     }
 
   }]

+ 15 - 13
frameworks/CSharp/revenj/benchmark_config.json

@@ -1,5 +1,5 @@
 {
-  "framework": "Revenj.NET",
+  "framework": "Revenj",
   "tests": [{
     "windows": {
       "setup_file": "setup",
@@ -11,18 +11,19 @@
       "fortune_url": "/bench/fortunes",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "Postgres",
       "database_os": "Linux",
-      "framework": "Revenj.NET",
+      "framework": "Revenj",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Full",
-      "platform": ".NET",
-      "webserver": "Revenj.NET",
+      "platform": "None",
+      "webserver": "None",
       "os": "Windows",
-      "display_name": "Revenj.NET",
+      "display_name": "Revenj",
       "notes": "",
-      "versus": ""
+      "versus": "Revenj"
     },
     "default": {
       "setup_file": "setup",
@@ -34,18 +35,19 @@
       "fortune_url": "/bench/fortunes",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "Postgres",
       "database_os": "Linux",
-      "framework": "Revenj.NET",
+      "framework": "Revenj",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Full",
-      "platform": "Mono",
-      "webserver": "Revenj.NET",
+      "platform": "None",
+      "webserver": "None",
       "os": "Linux",
-      "display_name": "Revenj.NET",
+      "display_name": "Revenj",
       "notes": "",
-      "versus": ""
+      "versus": "Revenj"
     }
   }]
 }

+ 58 - 44
frameworks/CSharp/servicestack/benchmark_config.json

@@ -7,18 +7,19 @@
       "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "None",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": "None",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "iis-sqlserver": {
       "setup_file": "setup_iis",
@@ -28,18 +29,19 @@
       "update_url": "/sqlserver/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "SQLServer",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": "None",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Windows",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "iis-mysql": {
       "setup_file": "setup_iis",
@@ -49,18 +51,19 @@
       "update_url": "/mysql/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "MySQL",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": "None",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "iis-postgresql": {
       "setup_file": "setup_iis",
@@ -70,18 +73,19 @@
       "update_url": "/postgresql/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "Postgres",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": "None",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "iis-mongodb": {
       "setup_file": "setup_iis",
@@ -92,18 +96,19 @@
       "update_url": "/mongodb/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "MongoDB",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Microsoft",
       "orm": "Raw",
-      "platform": "NET",
+      "platform": "None",
       "webserver": "IIS",
       "os": "Windows",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "nginx-default": {
       "setup_file": "setup_nginx",
@@ -111,18 +116,19 @@
       "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "None",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "nginx-sqlserver": {
       "setup_file": "setup_nginx",
@@ -132,12 +138,13 @@
       "update_url": "/sqlserver/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "SQLServer",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Windows",
@@ -153,18 +160,19 @@
       "update_url": "/mysql/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "MySQL",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "nginx-postgresql": {
       "setup_file": "setup_nginx",
@@ -174,18 +182,19 @@
       "update_url": "/postgresql/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "Postgres",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "nginx-mongodb": {
       "setup_file": "setup_nginx",
@@ -195,18 +204,19 @@
       "update_url": "/mongodb/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "MongoDB",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "xsp-default": {
       "setup_file": "setup_xsp",
@@ -214,18 +224,19 @@
       "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "None",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "XSP",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     }, 
     "xsp-sqlserver": {
       "setup_file": "setup_xsp",
@@ -235,18 +246,19 @@
       "update_url": "/sqlserver/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "SQLServer",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "XSP",
       "os": "Linux",
       "database_os": "Windows",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "xsp-mysql": {
       "setup_file": "setup_xsp",
@@ -256,18 +268,18 @@
       "update_url": "/mysql/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "MySQL",
       "framework": "servicestack",
       "language": "C#",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "XSP",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "xsp-postgresql": {
       "setup_file": "setup_xsp",
@@ -277,18 +289,19 @@
       "update_url": "/postgresql/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "Postgres",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "XSP",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     },
     "xsp-mongodb": {
       "setup_file": "setup_xsp",
@@ -298,18 +311,19 @@
       "update_url": "/mongodb/updates/",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Fullstack",
       "database": "MongoDB",
       "framework": "servicestack",
       "language": "C#",
+      "flavor": "Mono",
       "orm": "Raw",
-      "platform": "Mono",
+      "platform": "None",
       "webserver": "XSP",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "servicestack",
       "notes": "",
-      "versus": ""
+      "versus": "servicestack"
     }
   }]
 }

+ 2 - 1
frameworks/Clojure/aleph/benchmark_config.json

@@ -7,10 +7,11 @@
       "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Micro",
       "database": "None",
       "framework": "aleph",
       "language": "Clojure",
+      "flavor": "None",
       "orm": "Raw",
       "platform": "Netty",
       "webserver": "None",

+ 2 - 0
frameworks/Clojure/compojure/benchmark_config.json

@@ -15,6 +15,7 @@
       "database": "MySQL",
       "framework": "compojure",
       "language": "Clojure",
+      "flavor": "None",
       "orm": "Micro",
       "platform": "Servlet",
       "webserver": "Resin",
@@ -36,6 +37,7 @@
       "database": "MySQL",
       "framework": "compojure",
       "language": "Clojure",
+      "flavor": "None",
       "orm": "Raw",
       "platform": "Servlet",
       "webserver": "Resin",

+ 8 - 6
frameworks/Clojure/http-kit/benchmark_config.json

@@ -13,16 +13,17 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "MySQL",
-      "framework": "http-kit",
+      "framework": "None",
       "language": "Clojure",
+      "flavor": "None",
       "orm": "Micro",
-      "platform": "http-kit",
+      "platform": "Ring",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "http-kit",
       "notes": "",
-      "versus": ""
+      "versus": "http-kit"
     },
     "raw": {
       "setup_file": "setup",
@@ -34,16 +35,17 @@
       "approach": "Realistic",
       "classification": "Platform",
       "database": "MySQL",
-      "framework": "http-kit",
+      "framework": "None",
       "language": "Clojure",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "http-kit",
+      "platform": "Ring",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "http-kit",
       "notes": "",
-      "versus": ""
+      "versus": "http-kit"
     }
   }]
 }

+ 4 - 3
frameworks/Clojure/luminus/benchmark_config.json

@@ -11,18 +11,19 @@
       "update_url": "/updates/",
       "port": 3000,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Micro",
       "database": "Postgres",
       "framework": "luminus",
       "language": "Clojure",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Immutant",
+      "platform": "Ring",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "luminus",
       "notes": "",
-      "versus": "servlet"
+      "versus": "undertow"
     }
   }]
 }

+ 4 - 3
frameworks/Clojure/pedestal/benchmark_config.json

@@ -16,12 +16,13 @@
       "orm": "micro",
       "framework": "pedestal",
       "language": "Clojure",
-      "platform": "Servlet",
-      "webserver": "Jetty",
+      "flavor": "None",
+      "platform": "Undertow",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "pedestal",
-      "notes": "servlet"
+      "notes": "undertow"
     }
   }]
 }

+ 5 - 4
frameworks/Crystal/crystal-raw/benchmark_config.json → frameworks/Crystal/crystal/benchmark_config.json

@@ -7,18 +7,19 @@
       "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Micro",
+      "classification": "Platform",
       "database": "Postgres",
-      "framework": "crystal",
+      "framework": "None",
       "language": "Crystal",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Crystal",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "Crystal",
       "notes": "",
-      "versus": "ruby"
+      "versus": "crystal"
     }
   }]
 }

+ 0 - 0
frameworks/Crystal/crystal-raw/server.cr → frameworks/Crystal/crystal/server.cr


+ 0 - 0
frameworks/Crystal/crystal-raw/setup.sh → frameworks/Crystal/crystal/setup.sh


+ 6 - 4
frameworks/Crystal/kemal/benchmark_config.json

@@ -15,14 +15,15 @@
       "database": "Postgres",
       "framework": "kemal",
       "language": "Crystal",
+      "flavor": "None",
       "orm": "micro",
-      "platform": "Crystal",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "Kemal (PostgreSQL)",
       "notes": "",
-      "versus": "ruby"
+      "versus": "crystal"
     },
     "redis": {
       "setup_file": "setup-redis",
@@ -38,14 +39,15 @@
       "database": "Redis",
       "framework": "kemal",
       "language": "Crystal",
+      "flavor": "None",
       "orm": "micro",
-      "platform": "Crystal",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "Kemal (Redis)",
       "notes": "",
-      "versus": "ruby"
+      "versus": "crystal"
     }
   }]
 }

+ 4 - 27
frameworks/Crystal/kemal/server-postgres.cr

@@ -1,7 +1,6 @@
 require "kemal"
 require "pg"
 require "pool/connection"
-require "html_builder"
 
 # Compose Objects (like Hash) to have a to_json method
 require "json/to_json"
@@ -92,40 +91,17 @@ end
 
 # Postgres Test 4: Fortunes
 get "/fortunes" do |env|
+  env.response.content_type = CONTENT::HTML
   data = fortunes
-
   additional_fortune = {
     id:      0,
     message: "Additional fortune added at request time.",
   }
   data.push(additional_fortune)
 
-  data.sort_by! {|fortune| fortune[:message] }
+  data.sort_by! { |fortune| fortune[:message] }
 
-  env.response.content_type = CONTENT::HTML
-  # New builder for each request!
-  HTML::Builder.new.build do
-    doctype
-    html {
-      head {
-        title { html "Fortunes" }
-      }
-      body {
-        table {
-          tr {
-            th { html "id" }
-            th { html "message" }
-          }
-          data.each { |e|
-            tr {
-              td { html e[:id] }
-              td { text e[:message] }
-            }
-          }
-        }
-      }
-    }
-  end
+  render "views/fortunes.ecr"
 end
 
 # Postgres Test 5: Database Updates
@@ -138,4 +114,5 @@ get "/updates" do |env|
   updated.to_json
 end
 
+logging false
 Kemal.run

+ 2 - 25
frameworks/Crystal/kemal/server-redis.cr

@@ -1,6 +1,5 @@
 require "kemal"
 require "redis"
-require "html_builder"
 
 # Compose Objects (like Hash) to have a to_json method
 require "json/to_json"
@@ -96,30 +95,7 @@ get "/fortunes" do |env|
 
   data.sort_by! { |fortune| fortune[:message] }
 
-  env.response.content_type = CONTENT::HTML
-  # New builder for each request!
-  HTML::Builder.new.build do
-    doctype
-    html {
-      head {
-        title { html "Fortunes" }
-      }
-      body {
-        table {
-          tr {
-            th { html "id" }
-            th { html "message" }
-          }
-          data.each { |e|
-            tr {
-              td { html e[:id] }
-              td { text e[:message] }
-            }
-          }
-        }
-      }
-    }
-  end
+  render "views/fortunes.ecr"
 end
 
 # Redis Test 5: Database Updates
@@ -132,4 +108,5 @@ get "/updates" do |env|
   updated.to_json
 end
 
+logging false
 Kemal.run

+ 2 - 2
frameworks/Crystal/kemal/setup-postgres.sh

@@ -2,8 +2,8 @@
 
 fw_depends crystal
 
-crystal deps install
+shards install
 
 crystal build --release server-postgres.cr
 
-KEMAL_ENV=production ./server-postgres &
+./server-postgres &

+ 2 - 2
frameworks/Crystal/kemal/setup-redis.sh

@@ -2,8 +2,8 @@
 
 fw_depends crystal
 
-crystal deps install
+shards install
 
 crystal build --release server-redis.cr
 
-KEMAL_ENV=production ./server-redis &
+./server-redis &

+ 2 - 2
frameworks/Crystal/kemal/shard.lock

@@ -6,7 +6,7 @@ shards:
 
   kemal:
     github: sdogruyol/kemal
-    version: 0.14.1
+    version: 0.16.0
 
   kilt:
     github: jeromegn/kilt
@@ -22,7 +22,7 @@ shards:
 
   radix:
     github: luislavena/radix
-    version: 0.3.0
+    version: 0.3.1
 
   redis:
     github: stefanwille/crystal-redis

+ 3 - 5
frameworks/Crystal/kemal/shard.yml

@@ -10,11 +10,9 @@ dependencies:
     version: "0.2.3"
   kemal:
     github: "sdogruyol/kemal"
-    version: "0.14.1"
+    version: "0.16.0"
   redis:
     github: "stefanwille/crystal-redis"
-    version: "1.6.6"
-  html_builder:
-    github: "crystal-lang/html_builder"
-    version: "0.2.1"
+    version: "~> 1.6.6"
+
 license: "MIT"

+ 20 - 0
frameworks/Crystal/kemal/views/fortunes.ecr

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>Fortunes</title>
+</head>
+<body>
+	<table>
+		<tr>
+		<th>id</th>
+		<th>message</th>
+		</tr>
+		<% data.each do |fortune| %>
+			<tr>
+			<td><%= fortune[:id] %></td>
+			<td><%= HTML.escape(fortune[:message]) %></td>
+			</tr>
+		<% end %>
+	</table>
+</body>
+</html>

+ 6 - 4
frameworks/D/vibed/benchmark_config.json

@@ -11,12 +11,13 @@
       "update_url": "/updates?queries=",
       "port": 8080,
       "approach": "Realistic",
-      "classification": "Platform",
+      "classification": "Micro",
       "database": "MongoDB",
-      "framework": "vibed",
+      "framework": "vibe.d",
       "language": "D",
+      "flavor": "DLang2",
       "orm": "Micro",
-      "platform": "D",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
@@ -38,8 +39,9 @@
       "database": "MongoDB",
       "framework": "vibed",
       "language": "D",
+      "flavor": "DLang2",
       "orm": "Micro",
-      "platform": "D",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",

+ 4 - 3
frameworks/Dart/dart-raw/benchmark_config.json

@@ -10,13 +10,14 @@
       "update_url": "/updates?queries=",
       "plaintext_url": "/plaintext",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "Postgres",
-      "framework": "dart",
+      "framework": "None",
       "language": "Dart",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Dart",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",

+ 6 - 4
frameworks/Dart/redstone/benchmark_config.json

@@ -15,12 +15,13 @@
       "database": "Postgres",
       "framework": "redstone",
       "language": "Dart",
+      "flavor": "None",
       "orm": "Micro",
-      "platform": "Dart",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "redstone-postgresql",
+      "display_name": "redstone",
       "notes": "",
       "versus": "dart"
     },
@@ -36,12 +37,13 @@
       "database": "MongoDB",
       "framework": "redstone",
       "language": "Dart",
+      "flavor": "None",
       "orm": "Micro",
-      "platform": "Dart",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "redstone-mongodb",
+      "display_name": "redstone",
       "notes": "",
       "versus": "dart"
     }

+ 4 - 2
frameworks/Dart/start/benchmark_config.json

@@ -15,8 +15,9 @@
       "database": "Postgres",
       "framework": "start",
       "language": "Dart",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Dart",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
@@ -36,8 +37,9 @@
       "database": "MongoDB",
       "framework": "start",
       "language": "Dart",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Dart",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",

+ 4 - 2
frameworks/Dart/stream/benchmark_config.json

@@ -15,8 +15,9 @@
       "database": "Postgres",
       "framework": "stream",
       "language": "Dart",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Dart",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",
@@ -36,8 +37,9 @@
       "database": "MongoDB",
       "framework": "stream",
       "language": "Dart",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Dart",
+      "platform": "None",
       "webserver": "nginx",
       "os": "Linux",
       "database_os": "Linux",

+ 7 - 6
frameworks/Elixir/cowboy/benchmark_config.json

@@ -6,17 +6,18 @@
             "json_url": "/json",
             "plaintext_url": "/plaintext",
             "port": 8080,
-            "approach": "Realistic",
+            "approach": "Stripped",
             "classification": "Platform",
             "database": "None",
-            "framework": "cowboy",
-            "language": "elixir",
+            "framework": "None",
+            "language": "Elixir",
+            "flavor": "None",
             "orm": "raw",
-            "platform": "Erlang/OTP",
-            "webserver": "cowboy",
+            "platform": "None",
+            "webserver": "None",
             "os": "Linux",
             "database_os": "Linux",
-            "display_name": "elixir-cowboy",
+            "display_name": "Cowboy",
             "notes": "",
             "versus": ""
         }

+ 4 - 3
frameworks/Elixir/phoenix/benchmark_config.json

@@ -14,10 +14,11 @@
             "classification": "Micro",
             "database": "Postgres",
             "framework": "Phoenix",
-            "language": "elixir",
+            "language": "Elixir",
+            "flavor": "None",
             "orm": "full",
-            "platform": "Erlang/OTP",
-            "webserver": "cowboy",
+            "platform": "Cowboy",
+            "webserver": "None",
             "os": "Linux",
             "database_os": "Linux",
             "display_name": "Phoenix",

+ 4 - 3
frameworks/Erlang/chicagoboss/benchmark_config.json

@@ -9,11 +9,12 @@
       "approach": "Realistic",
       "classification": "Fullstack",
       "database": "None",
-      "framework": "chicagoboss",
+      "framework": "ChicagoBoss",
       "language": "Erlang",
+      "flavor": "None",
       "orm": "raw",
-      "platform": "cowboy",
-      "webserver": "cowboy",
+      "platform": "Cowboy",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "ChicagoBoss",

+ 5 - 4
frameworks/Erlang/cowboy/benchmark_config.json

@@ -8,17 +8,18 @@
       "db_url": "/db",
       "query_url": "/query?queries=",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "MySQL",
-      "framework": "cowboy",
+      "framework": "None",
       "language": "Erlang",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Cowboy",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "cowboy",
+      "display_name": "Cowboy",
       "notes": "",
       "versus": ""
   }}]

+ 4 - 3
frameworks/Erlang/elli/benchmark_config.json

@@ -7,13 +7,14 @@
       "json_url": "/json",
       "db_url": "/db",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "MySQL",
-      "framework": "elli",
+      "framework": "None",
       "language": "Erlang",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "elli",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",

+ 4 - 3
frameworks/Erlang/mochiweb/benchmark_config.json

@@ -6,13 +6,14 @@
       "json_url": "/json",
       "plaintext_url": "/plaintext",
       "port": 8080,
-      "approach": "Realistic",
+      "approach": "Stripped",
       "classification": "Platform",
       "database": "MySQL",
-      "framework": "Mochiweb",
+      "framework": "None",
       "language": "Erlang",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Erlang",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",

+ 2 - 1
frameworks/Go/beego/benchmark_config.json

@@ -12,8 +12,9 @@
       "database": "MySQL",
       "framework": "beego",
       "language": "Go",
+      "flavor": "None",
       "orm": "Micro",
-      "platform": "Go",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",

+ 13 - 10
frameworks/Go/echo/benchmark_config.json

@@ -12,15 +12,16 @@
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",
-      "database": "Postgres",
-      "framework": "echo",
+      "database": "MySQL",
+      "framework": "None",
       "language": "Go",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Go",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "echo",
+      "display_name": "Echo",
       "notes": "",
       "versus": "go"
     },
@@ -36,14 +37,15 @@
       "approach": "Realistic",
       "classification": "Micro",
       "database": "Postgres",
-      "framework": "echo",
+      "framework": "None",
       "language": "Go",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Go",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "echo-std",
+      "display_name": "Echo-std",
       "notes": "",
       "versus": "go"
     },
@@ -59,14 +61,15 @@
       "approach": "Realistic",
       "classification": "Micro",
       "database": "Postgres",
-      "framework": "echo",
+      "framework": "None",
       "language": "Go",
+      "flavor": "None",
       "orm": "Raw",
-      "platform": "Go",
+      "platform": "None",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "echo-prefork",
+      "display_name": "Echo-prefork",
       "notes": "",
       "versus": "go"
     }

+ 1 - 0
frameworks/Go/echo/setup.sh

@@ -4,6 +4,7 @@ fw_depends go
 
 go get github.com/labstack/echo/...
 go get github.com/lib/pq
+go get github.com/valyala/tcplisten
 go install standard fasthttp
 
 fasthttp &

Some files were not shown because too many files changed in this diff