Browse Source

Improve akka-http fortunes: (#4594)

- Upgrade to scalate 1.9.1 (sanitization performance improvement https://github.com/scalate/scalate/pull/204) and Scala 2.12.8
- avoid allocations when adding a fortune and sorting fortunes
- use column indices instead of names to avoid expensive building of columns index
- increase thread and connection pool to match the maximum concurrency of the fortunes benchmark: 512
Rafał Sumisławski 6 years ago
parent
commit
d46e66ee93

+ 2 - 2
frameworks/Scala/akka-http/akka-http/build.sbt

@@ -6,7 +6,7 @@ name := "akka-http-benchmark"
 
 version := "0.1.0-SNAPSHOT"
 
-scalaVersion := "2.12.5"
+scalaVersion := "2.12.8"
 
 resolvers += "Akka Snapshot Repository" at "http://repo.akka.io/snapshots/"
 
@@ -16,7 +16,7 @@ libraryDependencies ++= Seq(
   "de.heikoseeberger" %% "akka-http-jsoniter-scala" % "1.23.0",
   "mysql" % "mysql-connector-java" % "5.1.47",
   "com.zaxxer" % "HikariCP" % "3.3.0",
-  "org.scalatra.scalate" %% "scalate-core" % "1.8.0",
+  "org.scalatra.scalate" %% "scalate-core" % "1.9.1",
   "org.scalatest" %% "scalatest" % "3.0.5" % "test"
 )
 

+ 2 - 2
frameworks/Scala/akka-http/akka-http/src/main/resources/application.conf

@@ -19,8 +19,8 @@ akka {
         dbuser: "benchmarkdbuser"
         dbpass: "benchmarkdbpass"
         jdbc-url: "jdbc:mysql://"${akka.http.benchmark.mysql.dbhost}":"${akka.http.benchmark.mysql.dbport}"/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true&useSSL=false"
-        connection-pool-size: 128
-        thread-pool-size: 128
+        connection-pool-size: 512
+        thread-pool-size: 512
       }
     }
     server {

+ 1 - 1
frameworks/Scala/akka-http/akka-http/src/main/scala/com/typesafe/akka/http/benchmark/datastore/DataStore.scala

@@ -12,5 +12,5 @@ trait DataStore {
 
   def updateWorld(world: World): Future[Boolean]
 
-  def getFortunes: Future[immutable.Seq[Fortune]]
+  def getFortunes: Future[Seq[Fortune]]
 }

+ 11 - 4
frameworks/Scala/akka-http/akka-http/src/main/scala/com/typesafe/akka/http/benchmark/datastore/MySqlDataStore.scala

@@ -2,6 +2,8 @@ package com.typesafe.akka.http.benchmark.datastore
 
 import java.sql.PreparedStatement
 import java.sql.ResultSet
+import java.util
+import java.util.Comparator
 import java.util.concurrent.Executors
 
 import com.typesafe.akka.http.benchmark.Infrastructure
@@ -37,7 +39,7 @@ trait MySqlDataStore extends DataStore { _: Infrastructure =>
     withStatement("select id, randomNumber from World where id = ?") { stmt =>
       stmt.setInt(1, id)
       val rs = stmt.executeQuery()
-      if (rs.next()) Some(World(rs.getInt("id"), rs.getInt("randomNumber")))
+      if (rs.next()) Some(World(rs.getInt(1), rs.getInt(2)))
       else None
     }
 
@@ -48,11 +50,16 @@ trait MySqlDataStore extends DataStore { _: Infrastructure =>
       stmt.executeUpdate() > 0
     }
 
-  override def getFortunes: Future[immutable.Seq[Fortune]] =
+  override def getFortunes: Future[Seq[Fortune]] =
     withStatement("select id, message from Fortune") { stmt =>
       val rs = stmt.executeQuery()
-      (Fortune(0, "Additional fortune added at request time.") +: rs.map(r => Fortune(r.getInt("id"), r.getString("message"))).toVector)
-        .sortBy(_.message)
+      val fortunes = (
+        Iterator.single(Fortune(0, "Additional fortune added at request time."))
+        ++ rs.map(r => Fortune(r.getInt(1), r.getString(2)))
+      ).toArray
+
+      util.Arrays.sort(fortunes, Ordering.by((f: Fortune) => f.message): Comparator[Fortune])
+      fortunes
     }
 
   private def withStatement[T](statement: String)(f: PreparedStatement => T): Future[T] =

+ 2 - 2
frameworks/Scala/akka-http/akka-http/src/main/scala/com/typesafe/akka/http/benchmark/handlers/FortunesHandler.scala

@@ -1,6 +1,6 @@
 package com.typesafe.akka.http.benchmark.handlers
 
-import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
+import akka.http.scaladsl.marshalling.{ Marshaller, ToEntityMarshaller }
 import akka.http.scaladsl.model.HttpCharsets._
 import akka.http.scaladsl.model.MediaTypes._
 import akka.http.scaladsl.model._
@@ -16,7 +16,7 @@ trait FortunesHandler { _: Infrastructure with DataStore with Templating =>
   def fortunesEndpoint: Route =
     get {
       path("fortunes") {
-        onSuccess(getFortunes)(complete(_))
+        complete(getFortunes)
       }
     }