四种Eval测试结果:不要用CodeDom做大批量的表达式四则运算
来源:互联网 发布:丽晶软件下载 编辑:程序博客网 时间:2024/05/16 00:32
有时候需要表达式运算,如
String strExpression="-12 * ( - 2.2 + 7.7 ) - 44 * 2";
网上找的,一般是利用CodeDom,见
http://www.codeproject.com/csharp/runtime_eval.asp
简化为:
System.CodeDom.Compiler.ICodeCompiler comp = (new Microsoft.CSharp.CSharpCodeProvider().CreateCompiler());
System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters();
object qswhEval2(string Expression){
StringBuilder code = new StringBuilder();
code.Append("using System; /n");
code.Append("namespace ADOGuy { /n");
code.Append(" public class _Evaluator { /n");
code.Append(" public object __foo() ");
code.Append("{ ");
code.AppendFormat(" return ({0}); ", Expression);
code.Append("}/n");
code.Append("} }");
System.CodeDom.Compiler.CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
System.Reflection.Assembly a = cr.CompiledAssembly;
object _Compiled = a.CreateInstance("ADOGuy._Evaluator");
System.Reflection.MethodInfo mi = _Compiled.GetType().GetMethod("__foo");
return mi.Invoke(_Compiled, null);
}
但用起来感觉很慢,毕竟需要实时编译。
于是,就自己照数据结构书上写了一种算法:
string Precede(string p, string q){
switch(p){
case "+":
case "-":return ("*/(".IndexOf(q)!=-1)?"<":">";
case "*":
case "/":return (q=="(")?"<":">";
case "(":return (q==")")?"=":"<";
case ")":return (q=="(")?"?":">";
case "#":return (q=="#")?"=":"<";
}
return "?";
}
Double Operate(Double a,char o,Double b)
{
switch(o)
{
case '+':return a+b;
case '-':return a-b;
case '*':return a*b;
case '/':return a/b;
}
return 0;
}
Object qswhEval1(string Expression){
/*************(qiushuiwuhen 2002-12-14)****************/
Stack nArr=new Stack(),oArr=new Stack();
int j=0;
Double a=0,b=0;
string w="";
char o;
MatchCollection arr=Regex.Matches(Expression.Replace(" ","")+"#",@"(((?<=(^|/())-)?/d+(/./d+)?|/D)");
oArr.Push('#');
w=Convert.ToString(arr[j++]);
while(!(w=="#"&&Convert.ToString(oArr.Peek())=="#")){
if("+-*/()#".IndexOf(w)!=-1){
switch(Precede(oArr.Peek().ToString(),w)){
case "<":
oArr.Push(w);
w=Convert.ToString(arr[j++]);
break;
case "=":
oArr.Pop();
w=Convert.ToString(arr[j++]);
break;
case ">":
o=Convert.ToChar(oArr.Pop());
b=Convert.ToDouble(nArr.Pop());
a=Convert.ToDouble(nArr.Pop());
nArr.Push(Operate(a,o,b));
break;
default:
return "Error";
break;
}
}else{
nArr.Push(w);
w=Convert.ToString(arr[j++]);
}
}
return nArr.Pop();
}
还有利用JScript的Eval的两种算法
Microsoft.JScript.Vsa.VsaEngine ve=Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
object qswhEval3(string Expression){
return Microsoft.JScript.Eval.JScriptEvaluate(Expression,ve);
}
object qswhEval4(string Expression){
return qswhJs.qswhEval.Eval(Expression);
}
第四种需先建立一js编译为dll,如下代码
import System;
package qswhJs {
class qswhEval {
static function Eval(Expression):Object { return eval(Expression); }
}
}
测试代码如下:
void Page_Load(Object o,EventArgs ea){
String strExpression="-12 * ( - 2.2 + 7.7 ) - 44 * 2";
int i=0,c=100;
DateTime d1,d2;
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
d1=DateTime.Now;
for(i=0;i<c;i++)qswhEval1(strExpression);
d2=DateTime.Now;
Response.Write("方法一:对表达式分析 "+d2.Subtract(d1)+"<br>");
d1=DateTime.Now;
for(i=0;i<c;i++)qswhEval2(strExpression);
d2=DateTime.Now;
Response.Write("方法二:利用CodeCom "+d2.Subtract(d1)+"<br>");
d1=DateTime.Now;
for(i=0;i<c;i++)qswhEval3(strExpression);
d2=DateTime.Now;
Response.Write("方法三:利用Jscript+Vsa "+d2.Subtract(d1)+"<br>");
d1=DateTime.Now;
for(i=0;i<c;i++)qswhEval4(strExpression);
d2=DateTime.Now;
Response.Write("方法四:利用Jsc+Dll "+d2.Subtract(d1)+"<br>");
}
测试结果:
方法一:对表达式分析 00:00:00.1702448
方法二:利用CodeCom 00:00:23.7942144
方法三:利用Jscript+Vsa 00:00:00.1902736
方法四:利用Jsc+Dll 00:00:00.2403456
在此推荐第一种(如果要纯CSharp的话)
和第三种(代码简单,功能更多)
- 四种Eval测试结果:不要用CodeDom做大批量的表达式四则运算
- 四种Eval测试结果:不要用CodeDom做大批量的表达式四则运算
- 输入四则运算的表达式,求解结果算法
- 用CodeDom、Reflection做一个简易计算器
- 用CodeDom、Reflection做一个简易计算器
- 栈的测试--四则运算表达式求值(C语言)
- 四则运算表达式的值
- 用Java模拟通过四则运算表达式字符串,构造逆波兰表达式,计算结果(转载一大牛)
- 用Java模拟通过四则运算表达式字符串,构造逆波兰表达式,计算结果
- 大批量更新数据mysql批量更新的四种方法
- 大批量更新数据mysql批量更新的四种方法
- 为什么不要用eval函数
- SqL四种写法测试结果
- CodeDom计算器——动态计算数学表达式的实现
- 利用栈对四则运算简单表达式求解的测试(中缀表达式)
- 字符串四则运算表达式的算法
- java中正则表达式用Pattern计算字符串的结果(四则运算);分成有括号和没括号;当然也可以采用逆波兰式
- 请不要做浮躁的人——软件测试
- 利用SharpZipLib实现实时zip压缩下载整个目录
- 自制Pop3邮件接收系统(一):利用MatchEvaluator实现HZ的解码
- 用regRange轻易实现特定数字范围的正则验证,如时间,IP等
- 自制Pop3邮件接收系统(二):利用TcpClient得到Pop3的邮件列表数据
- 利用filter实时切换big5和gb2312,以及gb2312的简繁体
- 四种Eval测试结果:不要用CodeDom做大批量的表达式四则运算
- 称三次从12球中找出唯一但不知轻重的球
- 数码图像中自动祛除红眼方法探讨
- File upload by JSP
- 兔八哥笔记1:java初学者笔记
- 兔八哥笔记2:JavaScript Editor简介
- 兔八哥笔记3:JSP自定义标签试验
- 兔八哥笔记4:《软件工程概论》读后感
- 兔八哥笔记6:XX管理系统项目笔记