Rythm 是如何 "作弊" 成性能第一的

原创
2019/12/28 06:05
阅读数 1.2K

昨天给波总的 模板引擎性能测试项目 提了一个 PR, 将 Rythm 加入测试对象列表中.

Rythm 加入后在我的环境下 (i7 8550U + 16G RAM + SSD) 跑完测试的情况如下:

# Run complete. Total time: 00:00:52

Benchmark         Mode  Cnt      Score      Error  Units
Beetl.benchmark  thrpt   10  47882.826 ±  659.766  ops/s
Enjoy.benchmark  thrpt   10  47030.326 ± 1474.265  ops/s
Rythm.benchmark  thrpt   10  57601.186 ± 5412.737  ops/s

注: 我直接使用 java -jar target/benchmark Beetl Enjoy Rythm 命令, 所以其他模板没有在测试结果当中

貌似 Rythm 力压 Beetl 和 Enjoy 成为了性能第一. 实际上这个性能第一有若干水分在里面, 下面来看看有那些水分, 以及挤掉水分之后的真实测试情况如何:

1. 测试方式

模板引擎最大量的应用场景是 Web 网页的后端生成. 很多引擎都是采用直接 Render 进 OutputStream, 而 Rythm 因为对布局继承的实现方式问题, 需要全部 Render 成字串然后再写入 OutputStream.

另一方面波总这个性能测试项目只要求引擎返回字串, 天生适合 Rythm 的输出方式. 如果我们把 Rythm 的测试代码稍微改改, 变成下面这个样子:

    @Benchmark
    public String benchmark() {
        ITemplate template = engine.getTemplate(TEMPLATE, context);
        String s = template.render();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        IO.write(s).to(os);
        return s;
    }

这个改动在 Rythm 的测试过程中模拟了写入 OutputStream 的过程. 重新运行测试的结果如下:

# Run complete. Total time: 00:00:52

Benchmark         Mode  Cnt      Score      Error  Units
Beetl.benchmark  thrpt   10  47744.054 ±  699.724  ops/s
Enjoy.benchmark  thrpt   10  46421.140 ±  490.437  ops/s
Rythm.benchmark  thrpt   10  44409.177 ± 3843.650  ops/s

上面这个改动让 Rythm 的输出性能已经降至 B, E 两个模板之后.

2. 屏蔽输出转义

Rythm 测试模板中我们看到循环输出部分被 @raw() block 给括起来了:

这个语义是告诉 Rythm 在 block 里面所有的变量输出都不要做转义 (Escape), 这个对于防范 XSS 攻击非常重要, 因此在正常情况下, 一般是不会这样做的.

去掉这个 @raw() block 之后运行测试的结果如下:

# Run complete. Total time: 00:00:52

Benchmark         Mode  Cnt      Score      Error  Units
Beetl.benchmark  thrpt   10  46858.943 ± 4395.426  ops/s
Enjoy.benchmark  thrpt   10  46731.298 ± 5901.519  ops/s
Rythm.benchmark  thrpt   10  40681.127 ± 1865.848  ops/s

这个时候 Rythm 的输出已经大大落后与 B 和 E 了.

3. 其他测试优化

在 Rythm 测试代码 中我特意加入了如下优化:

这些优化屏蔽掉了默认打开的以下配置:

关闭掉这些优化后测试结果如下:

# Run complete. Total time: 00:00:52

Benchmark         Mode  Cnt      Score     Error  Units
Beetl.benchmark  thrpt   10  48736.968 ± 420.824  ops/s
Enjoy.benchmark  thrpt   10  49213.322 ± 377.178  ops/s
Rythm.benchmark  thrpt   10  39498.101 ± 632.125  ops/s

4. 总结

经过上面的分析我们可以得到一下结论:

在 Rythm 提交的测试代码中主要有三种水分在其中:

  1. 没有写入 OutputStream, 水分比: 22%
  2. 关闭了输出转义, 水分比: 6%
  3. 其他测试优化, 水分比: 2%

挤掉以上水分之后 Rythm 的测试成绩排在 Beetl 以及 Enjoy 的成绩之后, 算是这个测试平台的 No.3

更新 2019-12-30

我将整个项目更新为全部输出到 OutputStream. 另外我发现项目中所有的测试都没有输出转义, 因此恢复了 Rythm 关闭输出转义以及其他测试优化, 重新运行测试之后的情况为:

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部