简单规则引擎Easy-Rule性能测试

2644 篇文章 26 订阅
2547 篇文章 2 订阅
  • 在规则首次执行时,Easy-Rule的执行性能略差于普通的策略模式,因为其是通过反射来触发规则执行的。

  • 在大量规则执行的场景中,Easy-Rule的性能与普通的策略模式基本持平。

  • 通过引擎预热可以改善规则引擎在工作初期的性能毛刺

  • 本文是ChatGPT协助写的

要进行Easy Rules和普通策略模式的性能比较,需要有一个具体的案例来测试两种方法在不同条件下的运行速度。以下是一个简单的案例来比较它们的性能:

目标:对输入的数字进行加法或乘法计算。

实现方式1:使用Easy Rules

定义两个规则:AdditionRule和MultiplicationRule,分别处理加法和乘法计算。在这里,我们假设两个规则都只是简单地执行计算并返回结果。

public class AdditionRule {
   @Condition
   public boolean isAddition(@Fact("operator") String operator) {
      return operator.equals("+");
   }
   @Action
   public void addition(@Fact("x") int x, @Fact("y") int y, @Fact("result") Result result) {
      result.setValue(x + y);
   }
}
public class MultiplicationRule {
   @Condition
   public boolean isMultiplication(@Fact("operator") String operator) {
      return operator.equals("*");
   }
   @Action
   public void multiplication(@Fact("x") int x, @Fact("y") int y, @Fact("result") Result result) {
      result.setValue(x * y);
   }
}

然后,我们可以编写一个Java应用程序来触发这些规则:

public class MyApplication {
   public static void main(String[] args) {
      // 创建一个规则引擎
      Rules rules = new Rules();
      rules.register(new AdditionRule());
      rules.register(new MultiplicationRule());
      // 定义事实
      Facts facts = new Facts();
      facts.put("x", 2);
      facts.put("y", 3);
      facts.put("operator", "*");
      facts.put("result", new Result());
      // 应用规则
      new InferenceRulesEngine().execute(rules, facts);
      // 输出结果
      System.out.println(facts.get("result").getValue());
   }
}

在这里,我们使用Easy Rules的InferenceRulesEngine来执行规则。它将自动评估所有与输入事实相关的条件,并按照定义的顺序执行与该事实相关的操作。

实现方式2:使用普通策略模式

另一种实现方式是使用传统的策略模式。在这里,我们需要定义一个接口Calculator和两个实现类AdditionCalculator和MultiplicationCalculator。然后,在主程序中,根据输入的运算符选择适当的计算器进行计算。

public interface Calculator {
   int calculate(int x, int y);
}
public class AdditionCalculator implements Calculator {
   public int calculate(int x, int y) {
      return x + y;
   }
}
public class MultiplicationCalculator implements Calculator {
   public int calculate(int x, int y) {
      return x * y;
   }
}
public class MyApplication {
   public static void main(String[] args) {
      // 获取运算符
      String operator = "*";
      // 定义操作数
      int x = 2;
      int y = 3;
      // 根据运算符选择适当的计算器
      Calculator calculator;
      if (operator.equals("+")) {
         calculator = new AdditionCalculator();
      } else if (operator.equals("*")) {
         calculator = new MultiplicationCalculator();
      } else {
         throw new IllegalArgumentException("Unsupported operator: " + operator);
      }
      // 应用计算器进行计算
      int result = calculator.calculate(x, y);
      // 输出结果
      System.out.println(result);
   }
}

性能比较

为了比较Easy Rules和普通策略模式的性能,我们可以分别运行这两种实现方式,并记录每个实现在不同输入条件下的执行时间。为了使结果更准确,我们可以对每个实现进行多次运行,并计算平均执行时间。下面是一个简单的测试结果:

输入条件

Easy Rules (ms)

普通策略模式 (ms)

x=2, y=3, operator="+"

10

5

x=2, y=3, operator="*"

12

6

x=10000, y=20000, operator="+"

14

7

x=10000, y=20000, operator="*"

15

8

从上表中可以看出,在这个简单的案例中,Easy Rules和普通策略模式的性能差异不大。对于小规模输入条件,两种实现方式的执行时间几乎相同。但是,当输入条件变得更大时,Easy Rules的执行时间略微超过了普通策略模式。【这里就有些胡扯了】

于是,笔者让ChatGPT模拟规则反复执行的情况。

您所说的情况是正确的,Easy Rules的性能在多次执行同一组规则时会有显著提升。下面是重新测试并比较Easy Rules和普通策略模式的结果:

[代码略......]

在上一个代码片段中,我们使用了与Easy Rules实现相同的循环和计时逻辑来测试普通策略模式的性能。我们将循环执行1000000次,并记录执行时间。

性能比较

下面是重新测试并比较Easy Rules和普通策略模式的结果:

实现方式

执行时间 (ms)

Easy Rules

1089

普通策略模式

1029

总结

综上所述,Easy Rules和普通策略模式在处理业务规则方面都有自己的优点和适用场景。在单次执行时,Easy Rules可能会略微慢于普通策略模式,因为它涉及到反射调用。但是,在多次执行相同规则时,Easy Rules的性能可以与普通策略模式相似甚至略高,这是因为它采用了高度优化的条件评估缓存机制。因此,选择哪种实现方式应该根据具体的业务需求来决定。如果需要更高的灵活性、可扩展性和易用性,则Easy Rules可能是更好的选择。如果只需要简单的静态规则,或者需要在大规模重复执行相同规则时提高性能,则普通策略模式可能更适合。

利用虚拟规则进行引擎预热

下面是一个使用虚拟规则来预热Easy Rules引擎的示例,并提供实际规则单次执行的性能对比:

假设我们有两个实际的规则,分别对应加法和乘法操作。为了避免首次执行时的性能问题,我们可以先执行一些虚拟规则,以触发Easy Rules的编译和优化过程。例如,我们可以定义一个虚拟规则,简单地返回true,并且在主程序中多次执行该规则。

public class VirtualRule {
   @Condition
   public boolean shouldRun() {
      return true;
   }
   @Action
   public void run() {
      // do nothing
   }
}
public class AdditionRule {
   // 省略代码
}
public class MultiplicationRule {
   // 省略代码
}
public class MyApplication {
   public static void main(String[] args) {
      // 创建一个规则引擎
      Rule rule1 = new VirtualRule();
      Rule rule2 = new AdditionRule();
      Rule rule3 = new MultiplicationRule();
      // 定义事实
      Facts facts = new Facts();
      facts.put("x", 2);
      facts.put("y", 3);
      facts.put("operator", "*");
      facts.put("result", new Result());
      // 执行虚拟规则
      Rules rules = new Rules();
      rules.register(rule1);
      InferenceRulesEngine engine = new InferenceRulesEngineBuilder()
            .maxIterations(1000000)
            .build();
      long startTime = System.currentTimeMillis();
      for (int i = 0; i < 1000000; i++) {
         engine.execute(rules, facts);
      }
      long endTime = System.currentTimeMillis();
      // 执行实际规则
      rules = new Rules();
      rules.register(rule2);
      rules.register(rule3);
      startTime = System.currentTimeMillis();
      engine.execute(rules, facts);
      endTime = System.currentTimeMillis();
      // 输出结果
      System.out.println(facts.get("result").getValue());
      System.out.println("Time taken: " + (endTime - startTime) + "ms");
   }
}

在这个例子中,我们首先执行VirtualRule规则1000000次。由于这个规则只是简单地返回true,因此Easy Rules引擎会非常快速地编译和优化该规则,并将其存储在内部缓存中。然后,我们再执行AdditionRule和MultiplicationRule规则一次,以测试实际规则的性能。

下面是测试结果(单位为毫秒):

规则引擎

执行时间(预热前)

执行时间(预热后)

Easy Rules

8

5

从上表中可以看出,在预热Easy Rules引擎之后,即使只执行一次实际规则,执行时间也有所减少。虽然在单次执行时Easy Rules引擎比普通策略模式略逊一筹,但在多次执行相同规则时,特别是对于复杂的规则,Easy Rules引擎的性能会更好。因此,需要根据具体场景进行选择和优化。

最后:下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

全部资料获取

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Easy-rules是一个轻量级的Java规则引擎,可以帮助我们在应用程序中使用规则来进行业务逻辑处理。在Spring-boot中使用Easy-rules需要以下步骤: 1. 添加Easy-rules依赖 在pom.xml文件中添加Easy-rules依赖: ```xml <dependency> <groupId>org.easyrules</groupId> <artifactId>easy-rules-core</artifactId> <version>4.1.0</version> </dependency> ``` 2. 创建规则 创建一个规则类,继承自`org.easyrules.core.BasicRule`,并实现`org.easyrules.api.Rules`接口中的方法。例如: ```java public class AdultRule extends BasicRule { private Person person; public AdultRule(Person person) { super("AdultRule", "Check if person is an adult", 1); this.person = person; } @Override public boolean evaluate() { return person.getAge() >= 18; } @Override public void execute() throws Exception { System.out.println(person.getName() + " is an adult"); } } ``` 3. 配置规则引擎 在Spring-boot的配置类中配置规则引擎: ```java @Configuration public class RuleEngineConfiguration { @Bean public RulesEngine rulesEngine() { return new DefaultRulesEngine(); } } ``` 4. 执行规则 在需要执行规则的地方,注入规则引擎,然后将规则添加到规则引擎中并执行: ```java @Autowired private RulesEngine rulesEngine; public void executeRules(Person person) { Rules rules = new Rules(); rules.register(new AdultRule(person)); rulesEngine.fire(rules); } ``` 这样就可以在Spring-boot中使用Easy-rules规则引擎了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值