Skip to content

Jmh benchmark #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 56 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.jeroenreijn</groupId>
<artifactId>spring-comparing-template-engines</artifactId>
<packaging>war</packaging>
<packaging>jar</packaging>
<version>0.8.0-SNAPSHOT</version>
<name>template-engines</name>

Expand Down Expand Up @@ -40,6 +40,7 @@
<liqp.version>0.7.9</liqp.version>
<kotlin.version>1.7.20</kotlin.version>
<kotlinx.html.version>0.8.0</kotlinx.html.version>
<jmh.version>1.35</jmh.version>
</properties>

<parent>
Expand Down Expand Up @@ -269,8 +270,23 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--Benchmarking should not be on test, however a mock is required for benchmarking -->
<!--spring-boot-starter-test only for benchmarking!-->
<!-- <scope>test</scope> -->
</dependency>

<!-- Benchmark -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>provided</scope>
</dependency>

</dependencies>

Expand Down Expand Up @@ -324,7 +340,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
Expand Down Expand Up @@ -355,6 +370,43 @@
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>shade-my-jar</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<!--
Shading signed JARs will fail without this.
http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
-->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

<pluginManagement>
Expand Down
154 changes: 154 additions & 0 deletions src/main/java/com/jeroenreijn/examples/LaunchJMH.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package com.jeroenreijn.examples;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import java.util.concurrent.TimeUnit;

import static java.lang.String.format;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

/**
* Some code on this class has been sampled from https://stackoverflow.com/a/41499972
*/
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
public class LaunchJMH {

static ConfigurableApplicationContext context;
static MockMvc mockMvc;

@Setup(Level.Trial)
public synchronized void startupSpring() {
try {
if (context == null) {
context = SpringApplication.run(Launch.class);
mockMvc = MockMvcBuilders
.webAppContextSetup((WebApplicationContext) context)
.build();
}
} catch (Exception e) {
//Force JMH crash
throw new RuntimeException(e);
}
}

@TearDown(Level.Trial)
public synchronized void shutdownSpring() {
try {
if (context != null) {
SpringApplication.exit(context);
context = null;
}
} catch (Exception e) {
//Force JMH crash
throw new RuntimeException(e);
}
}

private String benchmarkTemplate(String template) {
try {
ResultActions res = mockMvc.perform(
get(format("/%s", template))
.accept(MediaType.ALL_VALUE)
);
return res.andReturn().getResponse().getContentAsString();
} catch (Exception e) {
//Force JMH crash
throw new RuntimeException(e);
}
}
@Benchmark
public String benchmarkChunk() {
return benchmarkTemplate("chunk");
}
@Benchmark
public String benchmarkFreemarker() {
return benchmarkTemplate("freemarker");
}
@Benchmark
public String benchmarkGroovy() {
return benchmarkTemplate("groovy");
}
@Benchmark
public String benchmarkHandlebars() {
return benchmarkTemplate("handlebars");
}
@Benchmark
public String benchmarkHtmlFlow() {
return benchmarkTemplate("htmlFlow");
}
@Benchmark
public String benchmarkHttl() {
return benchmarkTemplate("httl");
}
@Benchmark
public String benchmarkIckenham() {
return benchmarkTemplate("ickenham");
}
@Benchmark
public String benchmarkJade() {
return benchmarkTemplate("jade");
}
// Biased results because JSP resolver is not being invoked with MockMVC
// and it is always resolved with an empty view!!!!
@Benchmark
public String benchmarkJsp() {
return benchmarkTemplate("jsp");
}
@Benchmark
public String benchmarkKotlinxHtml() {
return benchmarkTemplate("kotlinx");
}
@Benchmark
public String benchmarkLiqp() {
return benchmarkTemplate("liqp");
}
@Benchmark
public String benchmarkMustache() {
return benchmarkTemplate("mustache");
}
@Benchmark
public String benchmarkPebble() {
return benchmarkTemplate("pebble");
}
@Benchmark
public String benchmarkRocker() {
return benchmarkTemplate("rocker");
}
@Benchmark
public String benchmarkRythm() {
return benchmarkTemplate("rythm");
}
@Benchmark
public String benchmarkScalate() {
return benchmarkTemplate("scalate");
}
@Benchmark
public String benchmarkThymeleaf() {
return benchmarkTemplate("thymeleaf");
}
@Benchmark
public String benchmarkTrimou() {
return benchmarkTemplate("trimou");
}
@Benchmark
public String benchmarkVelocity() {
return benchmarkTemplate("velocity");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.jeroenreijn.examples.controller", "com.jeroenreijn.examples.factory" })
@ComponentScan(basePackages = { "com.jeroenreijn.examples.controller", "com.jeroenreijn.examples" })
public class WebMvcConfig implements ApplicationContextAware, WebMvcConfigurer {
private ApplicationContext applicationContext;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ class KotlinxHtmlIndexView {
fun presentationsTemplate(presentations : Iterable<Presentation> ): String {
val output = StringBuilder()
output
.appendLine("<!DOCTYPE html>")
.appendHTML()
.html {
head {
meta {charset = "utf-8" }
meta {name = "viewport"; content = "width=device-width, initial-scale=1.0" }
meta {httpEquiv=MetaHttpEquiv.contentLanguage; content="IE=Edge" }
title { text("JFall 2013 Presentations - htmlApi")}
meta {httpEquiv="x-ua-compatible"; content="IE=Edge" }
title { text("JFall 2013 Presentations - kotlinx.html")}
link {rel=LinkRel.stylesheet; href="/webjars/bootstrap/4.3.1/css/bootstrap.min.css"; media = LinkMedia.screen;}
}
body {
Expand All @@ -32,7 +33,7 @@ class KotlinxHtmlIndexView {
classes = setOf("card mb-3 shadow-sm rounded")
div {
classes = setOf("card-header")
h3 {
h5 {
classes = setOf("card-title")
text( it.title + " - " + it.speakerName)
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/freemarker/includes.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<title>[@spring.message code="example.title"/] - Freemarker</title>
<link rel="stylesheet" href="${springMacroRequestContext.getContextPath()}/webjars/bootstrap/4.3.1/css/bootstrap.min.css" media="screen" />
<link rel="stylesheet" href="${springMacroRequestContext.getContextPath()}/webjars/bootstrap/4.3.1/css/bootstrap.min.css" media="screen"/>
</head>
[/#macro]

Expand Down
7 changes: 3 additions & 4 deletions src/main/resources/templates/groovy/base.tpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
yieldUnescaped '<!DOCTYPE html>'
html(lang:'en') {
html {
head {
include template: 'head.tpl'
}
Expand All @@ -11,7 +11,6 @@ html(lang:'en') {

mainBody()
}
include template: 'scripts.tpl'
}

include template: 'scripts.tpl'
}
}
2 changes: 1 addition & 1 deletion src/main/resources/templates/groovy/head.tpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
meta(charset: 'UTF8')
meta(charset: 'UTF-8')
meta(name: 'viewport', content: 'width=device-width, initial-scale=1.0')
meta('http-equiv': 'X-UA-Compatible', 'content': 'IE=Edge')
title(title)
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/httl/index-httl.httl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</div>
<!--#end-->
</div>
<script src=${contextPath}/webjars/jquery/3.1.1/jquery.min.js></script>
<script src=${contextPath}/webjars/bootstrap/4.3.1/js/bootstrap.min.js></script>
<script src="${contextPath}/webjars/jquery/3.1.1/jquery.min.js"></script>
<script src="${contextPath}/webjars/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion src/main/resources/templates/trimou/head.trimou
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<title>{{springMsg "example.title" "Unknown i18n"}} - Trimou</title>
<link rel="stylesheet" href="/webjars/bootstrap/4.3.1/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/webjars/bootstrap/4.3.1/css/bootstrap.min.css" media="screen"/>
</head>
2 changes: 1 addition & 1 deletion src/main/resources/templates/velocity/includes.vm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<title>#springMessage("example.title") - Velocity</title>
<link rel="stylesheet" href="$link.relative("/webjars/bootstrap/4.3.1/css/bootstrap.min.css")" media="screen" />
<link rel="stylesheet" href="$link.relative("/webjars/bootstrap/4.3.1/css/bootstrap.min.css")" media="screen"/>
</head>
#end

Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/velocity/index-velocity.vm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</div>
</div>
#end
#scripts()
</div>
#scripts()
</body>
</html>
</html>
2 changes: 1 addition & 1 deletion src/main/webapp/WEB-INF/handlebars/head.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<title>{{i18n "example.title"}} - Handlebars</title>
<link rel="stylesheet" href="{{springMacroRequestContext.contextPath}}/webjars/bootstrap/4.3.1/css/bootstrap.min.css"/>
<link rel="stylesheet" href="{{springMacroRequestContext.contextPath}}/webjars/bootstrap/4.3.1/css/bootstrap.min.css" media="screen"/>
</head>
2 changes: 1 addition & 1 deletion src/main/webapp/WEB-INF/handlebars/presentation.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="card mb-3 shadow-sm rounded">
<div class="card-header">
<h5 class="card-title">{{title}} - {{speakerName}}</h5>
<h5 class="card-title">{{{title}}} - {{speakerName}}</h5>
</div>
<div class="card-body">
{{{summary}}}
Expand Down
2 changes: 1 addition & 1 deletion src/main/webapp/WEB-INF/ickenham/head.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<title>{{i18n "example.title"}} - Ickenham</title>
<link rel="stylesheet" href="{{rc.contextPath}}/webjars/bootstrap/4.3.1/css/bootstrap.min.css"/>
<link rel="stylesheet" href="{{rc.contextPath}}/webjars/bootstrap/4.3.1/css/bootstrap.min.css" media="screen"/>
</head>
7 changes: 4 additions & 3 deletions src/main/webapp/WEB-INF/jade/layout.jade
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
doctype html
html
head
meta(name="charset", content="UTF-8")
title #{i18n.message("example.title")} - Jade4j
link(rel="stylesheet", href=springMacroRequestContext.contextPath + "/webjars/bootstrap/4.3.1/css/bootstrap.min.css")
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
meta(http-equiv="X-UA-Compatible", content="IE=Edge")
title #{i18n.message("example.title")} - Jade4j
link(rel="stylesheet", href=springMacroRequestContext.contextPath + "/webjars/bootstrap/4.3.1/css/bootstrap.min.css", media="screen")
body
.container
.pb-2.mt-4.mb-3.border-bottom
Expand Down
Loading