JSON API: fix benchmarks and avoid excessive iterations (#16963)

* reduce fork count, measurement and warmup iterations, and extra parameters which had a multiplicative effect on total work done
* fix db connection setup - the combination of annotations and inheritance meant it was trying to setup the trial twice, causing Postgres benchmarks to fail
* log when an error occurs during test setup
* add logback resources to the benchmarks, to enable configuration of logging, and avoid dumping all the debug logs by default

With these changes, on my 20 core 64G linux laptop, the benchmarks now all run in under 6 mins.
Without this change, it took over 9 hours in total and none of the Postgres benchmarks were successful.
This commit is contained in:
Raphael Speyer 2023-06-07 08:09:24 +10:00 committed by GitHub
parent 39f331ec7f
commit 1f351b418e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 16 deletions

View File

@ -670,6 +670,9 @@ exports_files(["src/main/resources/logback.xml"])
da_scala_benchmark_jmh(
name = "contractdao-bench",
srcs = glob(["src/bench/scala/**/*.scala"]),
resources = [
":src/main/resources/logback.xml",
],
scala_deps = [
"@maven//:org_scalaz_scalaz_core",
"@maven//:io_spray_spray_json",

View File

@ -38,7 +38,7 @@ abstract class ContractDaoBenchmark {
var batchSize: Int = _
@Setup(Level.Trial)
def setup(): Unit = {
def trialSetup(): Unit = {
connectToDb()
val cfg = createDbJdbcConfig
val cDao = ContractDao(cfg)
@ -47,10 +47,14 @@ abstract class ContractDaoBenchmark {
import cDao.jdbcDriver
dao.transact(ContractDao.initialize).unsafeRunSync()
trialSetupPostInitialize()
}
def trialSetupPostInitialize(): Unit
@TearDown(Level.Trial)
def teardown(): Unit = {
def trialTearDown(): Unit = {
dao.close()
cleanup()
}

View File

@ -14,7 +14,7 @@ import spray.json.DefaultJsonProtocol._
trait InsertBenchmark extends ContractDaoBenchmark {
self: BenchmarkDbConnection =>
@Param(Array("1", "3", "5", "7", "9"))
@Param(Array("1", "100"))
var batches: Int = _
@Param(Array("1000"))
@ -26,9 +26,7 @@ trait InsertBenchmark extends ContractDaoBenchmark {
private var tpid: SurrogateTpId = _
@Setup(Level.Trial)
override def setup(): Unit = {
super.setup()
override def trialSetupPostInitialize(): Unit = {
tpid = insertTemplate(ContractTypeId.Template("-pkg-", "M", "T"))
contracts = (1 until numContracts + 1).map { i =>
// Use negative cids to avoid collisions with other contracts
@ -50,6 +48,9 @@ trait InsertBenchmark extends ContractDaoBenchmark {
}
@Benchmark @BenchmarkMode(Array(Mode.AverageTime))
@Fork(1)
@Warmup(iterations = 1)
@Measurement(iterations = 1)
def run(): Unit = {
val inserted = dao.transact(queries.insertContracts(contracts)).unsafeRunSync()
assert(inserted == numContracts)

View File

@ -13,19 +13,17 @@ import org.openjdk.jmh.annotations._
trait QueryBenchmark extends ContractDaoBenchmark {
self: BenchmarkDbConnection =>
@Param(Array("1", "5", "9"))
@Param(Array("1", "10"))
var extraParties: Int = _
@Param(Array("1", "5", "9"))
@Param(Array("1", "10"))
var extraTemplates: Int = _
private val tpid = ContractTypeId.Template("-pkg-", "M", "T")
private var surrogateTpid: SurrogateTpId = _
val party = "Alice"
@Setup(Level.Trial)
override def setup(): Unit = {
super.setup()
override def trialSetupPostInitialize(): Unit = {
surrogateTpid = insertTemplate(tpid)
val surrogateTpids = surrogateTpid :: (0 until extraTemplates)
@ -44,6 +42,9 @@ trait QueryBenchmark extends ContractDaoBenchmark {
}
@Benchmark @BenchmarkMode(Array(Mode.AverageTime))
@Fork(1)
@Warmup(iterations = 3)
@Measurement(iterations = 10)
def run(): Unit = {
implicit val driver: SupportedJdbcDriver.TC = dao.jdbcDriver
val result = instanceUUIDLogCtx(implicit lc =>

View File

@ -17,10 +17,10 @@ import spray.json._
trait QueryPayloadBenchmark extends ContractDaoBenchmark {
self: BenchmarkDbConnection =>
@Param(Array("1", "10", "100"))
@Param(Array("1", "10"))
var extraParties: Int = _
@Param(Array("1", "100", "100"))
@Param(Array("1", "10"))
var extraPayloadValues: Int = _
private val tpid = ContractTypeId.Template("-pkg-", "M", "T")
@ -54,9 +54,7 @@ trait QueryPayloadBenchmark extends ContractDaoBenchmark {
def whereClause = predicate.toSqlWhereClause(dao.jdbcDriver)
@Setup(Level.Trial)
override def setup(): Unit = {
super.setup()
override def trialSetupPostInitialize(): Unit = {
surrogateTpid = insertTemplate(tpid)
val parties: List[String] = party :: (0 until extraParties).map(i => s"p$i").toList
@ -71,6 +69,9 @@ trait QueryPayloadBenchmark extends ContractDaoBenchmark {
}
@Benchmark @BenchmarkMode(Array(Mode.AverageTime))
@Fork(1)
@Warmup(iterations = 3)
@Measurement(iterations = 10)
def run(): Unit = {
implicit val sjd: SupportedJdbcDriver.TC = dao.jdbcDriver
val result = instanceUUIDLogCtx(implicit lc =>

View File

@ -71,6 +71,7 @@ trait PostgresAround {
logger.info(s"PostgreSQL has started on port $port.")
} catch {
case NonFatal(e) =>
logger.error(s"Error while starting postgres: $e")
lockedPort.unlock()
stopPostgresql(dataDir)
deleteRecursively(root)