前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.NET Flee 字符串表达式动态解析,怎么性能优化!!

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

作者头像
MaybeHC
发布2024-04-23 19:44:40
1100
发布2024-04-23 19:44:40
举报
文章被收录于专栏:技术之路技术之路

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条数据需要计算

第一种 直接循环
代码语言:javascript
复制
                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);这段代码提取出来,不参与循环,循环中只进行赋值。如下代码

代码语言:javascript
复制
                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); 构建表达式的时候就会进行变量检查,如果没有表达式里的变量就会抛出异常。

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

代码语言:javascript
复制
                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毫秒左右。

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

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Flee
    • 使用介绍
      • 性能优化
        • 第一种 直接循环
        • 第二种 共用表达式
    相关产品与服务
    云开发 CloudBase
    云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com