diff --git a/.gitignore b/.gitignore index 5508a94..b3f1835 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ target/ .project /.idea/* .vscode +results.csv diff --git a/README.md b/README.md index a6cbaf3..19a2005 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ JMH benchmark for popular Java template engines: Running the benchmark ====================== -1. Download the source code and build it (`mvn clean install`) +1. Download the source code and build it (`mvn clean package`) 2. (Optional) To run a benchmark for a single template, such as Mustache, use `java -jar target/benchmarks.jar Mustache` 3. Run the benchmark for `presentations` or `stocks` workload. E.g. for : `presentations` ```bash diff --git a/pom.xml b/pom.xml index 5daf679..fd6a358 100644 --- a/pom.xml +++ b/pom.xml @@ -25,8 +25,13 @@ 4.3.1 1.4.0 - 1.8.20 + 21 + 21 + 21 + + 2.0.0 0.8.0 + 0.4.0 @@ -233,6 +238,12 @@ ${kotlinx.html.version} + + nu.staldal + kotlin-html-builder + ${kotlin.html.builder.version} + + junit junit diff --git a/src/main/java/com/mitchellbosecke/benchmark/KotlinHtmlBuilder.java b/src/main/java/com/mitchellbosecke/benchmark/KotlinHtmlBuilder.java new file mode 100644 index 0000000..adbbec3 --- /dev/null +++ b/src/main/java/com/mitchellbosecke/benchmark/KotlinHtmlBuilder.java @@ -0,0 +1,29 @@ +package com.mitchellbosecke.benchmark; + +import com.mitchellbosecke.benchmark.model.Presentation; +import com.mitchellbosecke.benchmark.model.Stock; +import com.mitchellbosecke.benchmark.templates.PresentationsKotlin; +import com.mitchellbosecke.benchmark.templates.PresentationsKotlinHtmlBuilder; +import com.mitchellbosecke.benchmark.templates.StocksKotlin; +import com.mitchellbosecke.benchmark.templates.StocksKotlinHtmlBuilder; +import org.openjdk.jmh.annotations.Benchmark; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public class KotlinHtmlBuilder extends BaseBenchmark { + + private List stocks = Stock.dummyItems(); + private final Collection presentations = Presentation.dummyItems(); + + @Benchmark + public String stocks(){ + return StocksKotlinHtmlBuilder.Companion.stocksTemplate(stocks); + } + + @Benchmark + public String presentations() throws IOException { + return PresentationsKotlinHtmlBuilder.Companion.presentationsTemplate(presentations); + } +} diff --git a/src/main/java/com/mitchellbosecke/benchmark/templates/PresentationsKotlinHtmlBuilder.kt b/src/main/java/com/mitchellbosecke/benchmark/templates/PresentationsKotlinHtmlBuilder.kt new file mode 100644 index 0000000..5684b8c --- /dev/null +++ b/src/main/java/com/mitchellbosecke/benchmark/templates/PresentationsKotlinHtmlBuilder.kt @@ -0,0 +1,52 @@ +package com.mitchellbosecke.benchmark.templates + +import com.mitchellbosecke.benchmark.model.Presentation +import nu.staldal.kotlin.html.* + +class PresentationsKotlinHtmlBuilder { + companion object { + + fun presentationsTemplate(presentations : Collection ): String { + return htmlDoc(prettyPrint = false) { + html { + head { + meta("charset" to "utf-8") + meta("name" to "viewport", "content" to "width=device-width, initial-scale=1.0") + meta("httpEquiv" to "contentLanguage", "content" to "IE=Edge") + title { + text("JFall 2013 Presentations - htmlApi") + } + link( + "rel" to "stylesheet", + "href" to "/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css", + "media" to "screen" + ) + } + body { + div("class" to "container") { + div("class" to "page-header") { + h1 { text("JFall 2013 Presentations - htmlApi") } + } + + presentations.forEach { + div("class" to "panel panel-default") { + div("class" to "panel-heading") { + h3("class" to "panel-title") { + text(it.title + " - " + it.speakerName) + } + } + div("class" to "panel-body") { + text(it.summary) + } + } + } + } + + script("src" to "/webjars/jquery/3.1.1/jquery.min.js") + script("src" to "/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js") + } + } + } + } + } +} diff --git a/src/main/java/com/mitchellbosecke/benchmark/templates/StocksKotlinHtmlBuilder.kt b/src/main/java/com/mitchellbosecke/benchmark/templates/StocksKotlinHtmlBuilder.kt new file mode 100644 index 0000000..8cadffc --- /dev/null +++ b/src/main/java/com/mitchellbosecke/benchmark/templates/StocksKotlinHtmlBuilder.kt @@ -0,0 +1,59 @@ +package com.mitchellbosecke.benchmark.templates + +import com.mitchellbosecke.benchmark.model.Stock +import nu.staldal.kotlin.html.* + +class StocksKotlinHtmlBuilder { + companion object { + + fun stocksTemplate(stocks : List ): String { + return htmlDoc(prettyPrint = false) { + html { + head { + title { text("Stock Prices") } + meta("httpEquiv" to "contentType", "content" to "text/html; charset=UTF-8") + meta("httpEquiv" to "Content-Style-Type", "content" to "text/css") + meta("httpEquiv" to "Content-Script-Type", "content" to "text/javascript") + link("rel" to "shortcut icon", "href" to "/images/favicon.ico") + link("rel" to "stylesheet", "type" to "text/css", "href" to "/css/style.css", "media" to "all") + script("type" to "text/javascript", "src" to "/js/util.js") + style("type" to "text/css") { + unsafe("[body { color: #333333; line-height: 150%;}thead { font-weight: bold; background-color: #CCCCCC;}.odd { background-color: #FFCCCC;}.even { background-color: #CCCCFF;}.minus { color: #FF0000;}]]>") + } + } + body { + h1 { text("Stock Prices") } + table { + thead { + tr { + th { text("#") } + th { text("symbol") } + th { text("name") } + th { text("price") } + th { text("change") } + th { text("ratio") } + } + } + tbody { + var index = 0 + stocks.forEach { + tr("class" to if (index % 2 == 0) "even" else "odd") { + td { index++ } + td { a("href" to it.url) { text(it.name) } } + td { strong { text(it.price.toString()) } } + td(*if (it.change < 0) arrayOf("class" to "minus") else arrayOf()) { + text(it.change.toString()) + } + td(*if (it.ratio < 0) arrayOf("class" to "minus") else arrayOf()) { + text(it.ratio.toString()) + } + } + } + } + } + } + } + } + } + } +}