javamonkey / beetl2.0

beetl2.0
BSD 3-Clause "New" or "Revised" License
415 stars 113 forks source link

与Rocker的性能比较和包大小问题 #298

Closed takeseem closed 7 years ago

takeseem commented 7 years ago

问题

  1. 多次测试Beetl2和Rocker相比相差10%,貌似现在Rocker的优化和Beetl的原理一致,是不是beetl没什么优势?
  2. 虽然语法分析用了antlr,beetl2的包相比Rocker太大了,为什么这么大?
    64K rocker-runtime-0.17.0.jar
    296K    antlr4-runtime-4.5.1-1.jar
    492K    beetl-2.7.13.jar

测试代码

import java.io.IOException; import java.util.Map;

import org.beetl.core.Configuration; import org.beetl.core.GroupTemplate; import org.beetl.core.Template; import org.beetl.core.resource.ClasspathResourceLoader; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Setup;

public class Beetl2 extends BaseBenchmark {

private Map<String, Object> context;
private Template template;

@Setup
public void setup() throws IOException {
    ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("templates/");
    Configuration cfg = Configuration.defaultConfiguration();
    GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
    template = gt.getTemplate("stocks.beetl2.html");
    context = getContext();
}

@Benchmark
public String benchmark() throws IOException {
    template.binding("items", context.get("items"));
    return template.render();
}

public static void main(String[] args) throws IOException {
    Beetl2 btl = new Beetl2();
    btl.setup();
    System.out.println(btl.benchmark());
}

}

- templates/stocks.beetl2.html
```xml
<!DOCTYPE html>
<html>
<head>
<title>Stock Prices</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="shortcut icon" href="/images/favicon.ico" />
<link rel="stylesheet" type="text/css" href="/css/style.css" media="all" />
<script type="text/javascript" src="/js/util.js"></script>
<style type="text/css">
/*<![CDATA[*/
body {e
    color: #333333;
    line-height: 150%;
}

thead {
    font-weight: bold;
    background-color: #CCCCCC;
}

.odd {
    background-color: #FFCCCC;
}

.even {
    background-color: #CCCCFF;
}

.minus {
    color: #FF0000;
}

/*]]>*/
</style>

</head>

<body>

    <h1>Stock Prices</h1>

    <table>
        <thead>
            <tr>
                <th>#</th>
                <th>symbol</th>
                <th>name</th>
                <th>price</th>
                <th>change</th>
                <th>ratio</th>
            </tr>
        </thead>
        <tbody>
            <%
            var i = 0;
            for(item in items){%>
            <tr class="${i%2==0?'even':'obb'}">
                <td>${++i}</td>
                <td><a href="/stocks/${item.symbol}">${item.symbol}</a></td>
                <td><a href="${item.url}">${item.name}</a></td>
                <td><strong>${item.price}</strong></td>
                <td>${item.change}</td>
                <td>${item.ratio}</td>
            </tr>
            <%}%>
        </tbody>
    </table>

</body>
</html>
javamonkey commented 7 years ago

你这个beetl测试里,采用的的是开发模式,也就是每次模板渲染都会有io操作检测文件是否变化,作为性能测试,需要关闭这个功能

@Setup
public void setup() throws IOException {
  ......
  cfg.getResourceMap().put("autoCheck", "false");
  gt = new GroupTemplate(resourceLoader, cfg);

}

你这个性能基准测试我也用过,这是我的代码 https://github.com/javamonkey/template-benchmark/blob/master/src/main/java/com/mitchellbosecke/benchmark/Beetl.java

这个性能基准测试并未发挥beetl二进制输出的性能提升,这很有现实意义,因为serlvet是允许二进制输出的。我觉得你可以使用国内的一个基准测试再比较看看

http://git.oschina.net/kiang/teb

据我所知Rock将模板编译成class,beetl2.x并没有这么做。 如果你按照我的提示关闭beetl的开发模式在做性能测试,beetl的性能会比rock高30%左右。

包大小不做评论,这个功能相关。我认为beetl是唯一个功能全+性能优秀的模板引擎

takeseem commented 7 years ago

@javamonkey 感谢解惑。

我想性能并未有明显提升,原因可能是:我用的linux系统,内存24G(当前已用内存不到5G),文件信息都被操作系统buff,所以您提到的设置autoCheck=false,就算我未设置,每次对文件的检测对测试的影响也是微乎其微。

Benchmark              Mode  Cnt      Score     Error  Units
Beetl2.benchmark      thrpt   50  33723.862 ± 319.618  ops/s
Freemarker.benchmark  thrpt   50  17533.955 ± 214.203  ops/s
Rocker.benchmark      thrpt   50  34740.170 ± 431.368  ops/s
takeseem commented 7 years ago

@javamonkey 根据你的提示修改模板为itemLP

            for(item in items){%>
            <tr class="${itemLP.even?'even':'obb'}">
                <td>${itemLP.index}</td>
                <td><a href="/stocks/${item.symbol}">${item.symbol}</a></td>
                <td><a href="${item.url}">${item.name}</a></td>
                <td><strong>${item.price}</strong></td>
                <td>${item.change}</td>
                <td>${item.ratio}</td>
            </tr>
            <%}%>

详细4次测试的结果:

Benchmark              Mode  Cnt      Score     Error  Units
Beetl2.benchmark      thrpt   50  31453.142 ± 529.383  ops/s
Freemarker.benchmark  thrpt   50  17854.607 ± 282.363  ops/s
Rocker.benchmark      thrpt   50  35036.516 ± 616.753  ops/s

Benchmark              Mode  Cnt      Score     Error  Units
Beetl2.benchmark      thrpt   50  31580.362 ± 607.943  ops/s
Freemarker.benchmark  thrpt   50  17801.836 ± 352.300  ops/s
Rocker.benchmark      thrpt   50  34963.856 ± 803.761  ops/s

Benchmark              Mode  Cnt      Score     Error  Units
Beetl2.benchmark      thrpt   50  31634.440 ± 570.007  ops/s
Freemarker.benchmark  thrpt   50  17686.287 ± 393.554  ops/s
Rocker.benchmark      thrpt   50  34576.466 ± 829.317  ops/s

Benchmark              Mode  Cnt      Score     Error  Units
Beetl2.benchmark      thrpt   50  31677.010 ± 448.478  ops/s
Freemarker.benchmark  thrpt   50  17785.933 ± 381.069  ops/s
Rocker.benchmark      thrpt   50  35433.607 ± 665.933  ops/s
javamonkey commented 7 years ago

你这个性能测试跟我以前同样的测试https://github.com/javamonkey/template-benchmark 显示结果不一致,当然这是我10个月以前用Rocker0.1的这个基准测试来测试的,可能Rocker在性能上完善了。你最好把你的测试代码上放到github上我验证一下。

Rocker我注意到最近一直在完善,包括我说的二进制输出,他貌似也增加了这个功能。Beetl性能优化方案也是采用了很多开源技术采用的优化方案,这些技术方案对于做开源得来说,都是透明的可采用的,Rocker作为将模板编译成class,如果再加上一些这种公开的性能优化肯定会Beetl解释执行更好。但从目前你的测试结果,性能差不多。而编译成class的弊端很多,你只要了解一下国内HTTL的各种抱怨就知道了。

我建议你使用我推荐的TEB基准测试,我觉得那个测试还是比较准的,对于每个测试都单独使用重启虚拟机测试,很公平(Rocker不知道是否是这样,如果是只有一个虚拟机内测试,那把Beetl放在前面测试,不太公平),而且,各种测试数据都有(还测试了日期格式化,这个Beetl也做了很好性能优化),Rocker的测试数据较少,缺少输入大小,输出大小,虚拟机情况

javamonkey commented 7 years ago

我用了Rock0.17.0 做了测试,结果跟你不太一样,我显示的结果还是beetl较Rocker有性能较大优势,具体测试性能图可以从 http://bbs.ibeetl.com/bbs/bbs/topic/426-1.html 上看到。github上传图片失败了,如下是测试结果

Beetl.benchmark       thrpt   50  43809.542 ± 1107.215  ops/s
Freemarker.benchmark  thrpt   50  14637.029 ±  159.901  ops/s
Handlebars.benchmark  thrpt   50  17788.066 ±   94.608  ops/s
Mustache.benchmark    thrpt   50  19817.108 ±  222.112  ops/s
Rocker.benchmark      thrpt   50  36484.491 ±  443.269  ops/s
Thymeleaf.benchmark   thrpt   50   5166.191 ±   68.880  ops/s
Velocity.benchmark    thrpt   50   5387.483 ±  150.841  ops/s

我的是mac 笔记本,git上的代码 在 https://github.com/javamonkey/template-benchmark

takeseem commented 7 years ago

第一次看到Beetl时看到是解释执行性能还能达到这么高时,我是很震惊的——强悍 (HTTL确实很差,12年时公司有项目用,抱怨一大堆)

非常奇怪,我clone您的代码,beetl仅比rocker快7.5%,达不到你的快20%——谁在乎呢,解释型还能有这么高的性能:)

# Run complete. Total time: 00:02:33

Benchmark          Mode  Cnt      Score     Error  Units
Beetl.benchmark   thrpt   50  36150.948 ± 418.102  ops/s
Rocker.benchmark  thrpt   50  33628.564 ± 481.119  ops/s

最后如果能按功能组织jar就更好了,感谢 @javamonkey 的耐心解答,用beetl确实没错。