您现在的位置是:首页 > 文章详情

WastEl 表达式引擎性能测试 - 每秒千万次运算超强性能

日期:2024-11-18点击:165

简介

WAST是一个高性能Java工具集库包,包括JSON、YAML、CSV、HttpClient、JDBC和EL引擎.

下面是单独对WastEl性能测试,测试环境window10 处理器i5 JDK1.8 单线程 idea工具(服务器配置性能中等)

maven依赖

        <dependency>
            <groupId>io.github.wycst</groupId>
            <artifactId>wast</artifactId>
            <version>0.0.18</version>
        </dependency>

        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-core</artifactId>
            <version>1.36</version>
        </dependency>
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-generator-annprocess</artifactId>
            <version>1.36</version>
        </dependency>

测试代码

import io.github.wycst.wast.common.expression.CacheableExpression;
import io.github.wycst.wast.common.expression.Expression;
import io.github.wycst.wast.common.expression.compile.CompilerExpression;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.options.TimeValue;

import java.util.concurrent.TimeUnit;

/**
 * @Created by wangyc
 */
public class WastElPerSecondJmhTest {
    final static String staticEl = "1+2";
    final static String dynamicsEl = "a+a+a+b+b";
    final static Expression wastParsedEl;
    final static Expression wastCompiledEl;
    final static Fact fact = new Fact();

    public static class Fact {
        public int a = 1;
        public int b = 2;
        public int c = 3;
    }

    static {
        wastParsedEl = Expression.parse(dynamicsEl);
        wastCompiledEl = CompilerExpression.createEnvironment()
                .objectParameterClass(Fact.class)
                .variableTypes(int.class, "a", "b")
                .compile(dynamicsEl);
    }

    @Benchmark
    public Object staticExpr() {
        return Expression.eval(staticEl);
    }

    @Benchmark
    public Object cacheableStaticExpr() {
        return CacheableExpression.eval(staticEl);
    }

    @Benchmark
    public Object dynamicsDirect() {
        return Expression.evalParameters(dynamicsEl, fact.a, fact.b);
    }

    @Benchmark
    public Object dynamicsParsedWithPojo() {
        return wastParsedEl.evaluate(fact);
    }

    @Benchmark
    public Object dynamicsParsedWithParameters() {
        return wastParsedEl.evaluateParameters(fact.a, fact.b);
    }

    @Benchmark
    public Object compileParameters() {
        return wastCompiledEl.evaluateParameters(fact.a, fact.b);
    }

    @Benchmark
    public Object compilePojo() {
        return wastCompiledEl.evaluate(fact);
    }

    @Benchmark
    public Object javaCode() {
        return fact.a + fact.a + fact.a + fact.b + fact.b;
    }

    public static void main(String[] args) throws RunnerException {

        System.out.println("staticExpr                      result " + Expression.eval(staticEl));
        System.out.println("cacheableStaticExpr             result " + CacheableExpression.eval(staticEl));
        System.out.println("dynamicsDirect                  result " + Expression.evalParameters(dynamicsEl, fact.a, fact.b));
        System.out.println("dynamicsParsedWithPojo          result " + wastParsedEl.evaluate(fact));
        System.out.println("dynamicsParsedWithParameters    result " + wastParsedEl.evaluateParameters(fact.a, fact.b));
        Options options = new OptionsBuilder()
                .include(WastElPerSecondJmhTest.class.getName())
                .mode(Mode.Throughput)
                .timeUnit(TimeUnit.SECONDS)
                .warmupTime(TimeValue.seconds(3))
                .measurementTime(TimeValue.seconds(3))
                .forks(1)
                .build();
        new Runner(options).run();
    }
}

运行结果(ops/s 每秒运算次数)

Benchmark                                             Mode  Cnt          Score          Error  Units
WastElPerSecondJmhTest.cacheableStaticExpr           thrpt    5  171657564.516 ±  7995468.134  ops/s
WastElPerSecondJmhTest.compileParameters             thrpt    5  241759348.205 ± 15257569.604  ops/s
WastElPerSecondJmhTest.compilePojo                   thrpt    5  337235732.558 ± 15465646.140  ops/s
WastElPerSecondJmhTest.dynamicsDirect                thrpt    5    2303974.920 ±    54792.033  ops/s
WastElPerSecondJmhTest.dynamicsParsedWithParameters  thrpt    5   33469025.187 ±   433401.164  ops/s
WastElPerSecondJmhTest.dynamicsParsedWithPojo        thrpt    5   17290195.897 ±   502910.746  ops/s
WastElPerSecondJmhTest.javaCode                      thrpt    5  336520348.857 ± 14309011.816  ops/s
WastElPerSecondJmhTest.staticExpr                    thrpt    5   15374869.767 ±   325368.159  ops/s

结论

  • 解析模式下执行静态表达式在无缓存的情况下每秒1.5千万次(注包含解析过程)
  • 解析模式下执行静态表达式在有缓存的情况下每秒1.6亿次(只解析一次)
  • 编译模式下包含4次加法运算的动态表达式每秒最高3亿次基本上和java代码每秒运行的次数持平

测试类地址:  https://gitee.com/xiaoch0209/wast-jmh-test/blob/main/src/main/java/com/jmh/test/expression/WastElPerSecondJmhTest.java

第三方测试目前只加入过express-benchmark (作者闲.大赋),结果有两月没更新了,无奈自己贴下个人运行的结果

​public class Test {

    public static void main(String[] args) throws Exception {
        org.openjdk.jmh.Main.main(args);
    }

}


​

下面是在JDK17下运行 的结果(每秒运算次数)

Benchmark               Mode  Cnt           Score          Error  Units
Aviator.forExpresss    thrpt    5      394144.816 ±    43654.175  ops/s
Aviator.ifExpresss     thrpt    5     3963746.142 ±   131093.900  ops/s
Aviator.simpleExpress  thrpt    5     3308604.053 ±    25862.339  ops/s
Beetl.forExpresss      thrpt    5     1443597.295 ±    41988.440  ops/s
Beetl.ifExpresss       thrpt    5     4403695.596 ±   113498.704  ops/s
Beetl.reflect          thrpt    5       83723.859 ±    40897.270  ops/s
Beetl.simpleExpress    thrpt    5     4386398.540 ±   111306.217  ops/s
Groovy.ifExpresss      thrpt    5      303806.258 ±    12134.866  ops/s
Groovy.simpleExpress   thrpt    5      302431.969 ±     8039.171  ops/s
Jexl3.forExpresss      thrpt    5      747716.738 ±    25959.630  ops/s
Jexl3.ifExpresss       thrpt    5     3806159.078 ±    99125.411  ops/s
Jexl3.simpleExpress    thrpt    5     3413623.305 ±    56783.177  ops/s
JfireEL.ifExpresss     thrpt    5    34195894.961 ±   357271.824  ops/s
JfireEL.simpleExpress  thrpt    5    24998273.343 ±  2685584.807  ops/s
Liquor.forExpresss     thrpt    5   195481886.461 ±  2464897.556  ops/s
Liquor.ifExpresss      thrpt    5   205435909.028 ±  5286307.686  ops/s
Liquor.simpleExpress   thrpt    5   200625386.760 ±  2214530.143  ops/s
Mvel.forExpresss       thrpt    5        4415.331 ±       60.968  ops/s
Mvel.ifExpresss        thrpt    5      184213.448 ±    58112.716  ops/s
Mvel.simpleExpress     thrpt    5      253283.417 ±    42492.561  ops/s
Nashorn.ifExpresss     thrpt    5       13056.037 ±     2274.430  ops/s
Nashorn.simpleExpress  thrpt    5       12543.251 ±     1230.481  ops/s
Spel.ifExpresss        thrpt    5    19045225.353 ±   300079.309  ops/s
Spel.simpleExpress     thrpt    5    18670957.394 ±   203441.671  ops/s
WastEl.forExpresss     thrpt    5   702537069.120 ±  1918356.393  ops/s
WastEl.ifExpresss      thrpt    5  1102947933.898 ± 11004950.388  ops/s
WastEl.simpleExpress   thrpt    5   626007123.964 ± 14879444.442  ops/s

对结果有质疑的或者有感兴趣的也可以自己把代码拉下来试试

WastEl文档地址

查看WastEl文档

源码地址

原文链接:https://www.oschina.net/news/320983
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章