首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译后的表达式运行速度比解释版本慢得多。

编译后的表达式运行速度比解释版本慢得多。
EN

Stack Overflow用户
提问于 2011-05-11 11:43:02
回答 1查看 309关注 0票数 2

我有一个规则引擎,它支持两种操作模式:

  1. 编译到C#程序中,并链接到引擎
  2. ,解析为基于反向抛光堆栈的指令,并解释

规则是带有函数调用(max、min、sin、cos等)的简单算术表达式。

我会假设编译版本(即#1)是,比解释版本(即#2)快得多--事实上,这是首先采用编译模式的主要原因。然而,我的速度测试表明并非如此。

编译版本

代码语言:javascript
复制
Action<double>[] Rules = new[] { calc1, calc2, calc3 ... };
double[] v = new double[...];   // Variables

void calc1(double arg) { v[3]=v[12]+v[15]/v[20] };   // "x3=x12+x15/x20"
void calc2(double arg) { ... };
   :
// Start timer now
Rules.AsParallel().ForAll(r => r(...));
// End timer

解释版本

代码语言:javascript
复制
Expression[] Rules = ...
// Each rule is already parsed into an Expression object, which is a set of
// reverse-polish stack-based instructions.
// For example, "x3=x12+x15/x20" will be parsed to:
//     [ Push(12), Push(15), Push(20), Divide(), Add() ]
// Start timer now
Rules.AsParallel().ForAll(r => r.Evaluate(...));
// End timer

在这里,“表达式”是第三方库的一部分,该库将一个简单的字符串解析为一组简单的反波兰堆栈指令,然后可以对其进行解释。它不是LINQ中的表达式--树对象--只是为了澄清。

注意:不要担心并发性,因为在实际代码中,我按“层”对规则进行排序,并按顺序计算各层,每个层仅取决于在前几层中计算的值。这两种模式具有完全相同的层结构。

结果

令人震惊的是,解释版本运行的速度比编译版本快得多,平均是4倍!换句话说,编译后的版本需要用0.3s来运行大约1,200条规则,而解释版本平均需要0.08-0.1s。

我的电脑是一个如此双核的Core2。

我使用的是.NET 4.0,10。

在调试或发布版本中,性能是相似的。

我的问题

是什么导致了编译模式的显著放缓?

注意:我已经发布了一个可能的答案,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-11 12:16:53

.NET是一个JIT编译的环境,所以JIT编译的代码越多,它就越慢。可能有1,200个方法在执行时运行时是JIT编译的,而在解释模式下只有JIT编译了一次。我可能在编译模式的循环中看到了额外的JIT时间。

实验:

  1. 运行每个模式5次(只为了完成任何JIT编译和填充缓存)
  2. 时间50次运行,取平均

结果:

run

  • Interpreted编译模式: 1.6ms /模式: 5.3ms /运行

意见:

看来,在编译模式的第一次运行期间花费了大量时间。

编译模式的第二次运行速度已经与解释模式相似。

解释模式不会随着运行次数的增加而显著加快。

因此,我认为在第一次运行期间,规则代码是JIT编译的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5963649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档