.NET Flee 字符串表达式动态解析,怎么性能优化!!

Flee

使用介绍

Flee (支持 Net6.0, Net5.0, Netstandard2.1, Netstandard2.0)
动态解析的框架是有几个的,个人先使用了DynamicExpresso,但是需求中是需要支持IF/ELSE的,DynamicExpresso中支持三目运算,可以代替IF/ELSE,需要对字符串表达式进行IF/ELSE到三目运算的转换才能使用,之后发现了Flee直接支持。
DynamicExpresso和Flee相比较,个人感觉Flee的性能更好,支持的功能也比较多。Flee支持自定函数,可以进行类的导入,其他变量等各个框架都有的功能就不详细说了。大家可以体验自行对比下。

DynamicExpresso
Flee

在这里插入图片描述
在这里插入图片描述
Flee的用法都可以参照官网的demo进行使用,还是比较详细的。

性能优化

在我项目中的场景是需要对表达式相同,但其中变量不同的表达式进行多次运算。
我这里大概需要循环2w次左右,有2w条数据需要计算

第一种 直接循环

                for (int i = 0; i < scurveFormulasSource.Count; i++)
                {
                 	ExpressionContext context = new ExpressionContext();
                	context.Imports.AddType(typeof(Math));
                	 //赋值变量
                    foreach (var item in scurveFormulasSource[i])
                    {
                        context.Variables[item.Key.Replace("*", "")] = item.Value;
                    }
                	IGenericExpression<double> exp = context.CompileGeneric<double>(input.Text);
 
                    double result = Math.Round(exp.Evaluate(), 2);
                }

这样计算大概需要4s

第二种 共用表达式

因为我每次的表达式是相同的,所以我想着可以用一个表达式,也就是IGenericExpression<double> exp = context.CompileGeneric<double>(input.Text);这段代码提取出来,不参与循环,循环中只进行赋值。如下代码

                ExpressionContext context = new ExpressionContext();
                context.Imports.AddType(typeof(Math));
                IGenericExpression<double> exp = context.CompileGeneric<double>(input.Text);
                for (int i = 0; i < scurveFormulasSource.Count; i++)
                {
                	 //赋值变量
                    foreach (var item in scurveFormulasSource[i])
                    {
                        context.Variables[item.Key.Replace("*", "")] = item.Value;
                    }

                    double result = Math.Round(exp.Evaluate(), 2);
                }

这样的代码运行后会报错,提示找不到我定义的变量,在GenericExpression<double> exp = context.CompileGeneric<double>(input.Text); 构建表达式的时候就会进行变量检查,如果没有表达式里的变量就会抛出异常。

我们可以做如下处理,在构建表达式之前先对变量进行赋值定义,之后再修改值 这样就不会抛出异常了。如下

                ExpressionContext context = new ExpressionContext();
                context.Imports.AddType(typeof(Math));
                 //赋值变量
                foreach (var item in scurveFormulasSource[i])
                {
                	context.Variables[item.Key.Replace("*", "")] = item.Value;
                }
                IGenericExpression<double> exp = context.CompileGeneric<double>(input.Text);
                for (int i = 0; i < scurveFormulasSource.Count; i++)
                {
                	 //赋值变量
                    foreach (var item in scurveFormulasSource[i])
                    {
                        context.Variables[item.Key.Replace("*", "")] = item.Value;
                    }

                    double result = Math.Round(exp.Evaluate(), 2);
                }

在获取表达式之前先定义出变量,之后修改值,这样修改后本次的运行时间为20毫秒左右。

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3f60ifl542yok

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Maybe_ch

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值