- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我试图将动态编译与标准编译进行比较。而且动态编译好像慢了很多。根据我的基准测试,慢了 1400%。
下面是生成调用动态编译代码的委托(delegate)的方法:
public static Function Eval(string sCSCode)
{
CSharpCodeProvider c = new CSharpCodeProvider();
ICodeCompiler icc = c.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.CompilerOptions = "/optimize";
//cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public double sin(double x) { return Math.Sin(x); }");
sb.Append("public double cos(double x) { return Math.Cos(x); }");
sb.Append("public double sqrt(double x) { return Math.Sqrt(x); }");
sb.Append("public const double PI = Math.PI;");
sb.Append("public double Calculate(double x, double y){\n");
sb.Append("return " + sCSCode + "; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
throw new Exception("ERROR: " + cr.Errors[0].ErrorText);
return null;
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("Calculate");
return delegate(double x, double y)
{
object[] oParams = new object[2];
oParams[0] = x;
oParams[1] = y;
object s = mi.Invoke(o, oParams);
return (double)s;
};
}
这是我为测试其性能而创建的代码:
private double f1(double x, double y)
{
return Math.Sin(x) + Math.Cos(y);
}
private void button1_Click(object sender, EventArgs e)
{
double sum = 0;
long t1 = DateTime.Now.Ticks;
for (double x = 0; x <= 500; x += 0.1)
{
for (double y = 0; y <= 500; y += 0.1)
{
sum += f1(x, y);
}
}
t1 = DateTime.Now.Ticks - t1;
sum = 0;
var f2 = FunctionConstructor.Eval("Math.Sin(x) + Math.Cos(y)");
long t2 = DateTime.Now.Ticks;
for (double x = 0; x <= 500; x += 0.1)
{
for (double y = 0; y <= 500; y += 0.1)
{
sum += f2(x, y);
}
}
t2 = DateTime.Now.Ticks - t2;
long dt = t2 - t1;
double q = dt / (double)t1;
MessageBox.Show("WITHOUT dynamic compilation: " + t1 + "\n" + "WITH dynamic compilation: " + t2 + "\n" + "Calculation without dynamic compilation was " + dt + " ticks (" + (q-1)*100 + "%) slower");
}
根据我的测试,动态编译要慢得多。这能以某种方式解决吗?也许问题出在我进行基准测试的方式上?
最佳答案
您正在调用一个花费非常时间的方法。这使得调用方法的开销成为影响代码速度的主要因素。动态调用和无法内联方法都是时间 killer 。您可以通过在 Calculate 方法中移动内部循环来查看差异。例如:
sb.Append("public double Calculate(double x, double y){\n");
sb.Append("double sum = 0; for (; y <= 500; y += 0.1) {\n");
sb.Append("sum += " + sCSCode + ";\n");
sb.Append("} return sum;\n");
和
long t2 = DateTime.Now.Ticks;
for (double x = 0; x <= 500; x += 0.1) {
sum += f2(x, 0);
}
t2 = DateTime.Now.Ticks - t2;
您会发现差异消失了。对此没有简单的解决方法。问题不完全在于动态调用代码很慢,而是允许抖动优化器生成最佳机器代码使其速度如此之快。这当然是一项功能,而不是错误。
关于c# - 使用 CSharpCodeProvider 进行缓慢的动态编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14338738/
我根据随机大小的数据在内存中生成一些代码。这可以生成大约 15K 个类,甚至可能更多。代码存储在一个列表中,我使用 CSharpCodeProvider 类的 CompileAssemblyFromS
我正在使用一个在运行时编译的脚本系统,它运行良好,但是当我使用一些代码混淆器对“坏人”隐藏我的代码时,脚本停止工作,它返回一个错误: Error: CS0234 The type or namespa
不确定我问的是否是关于我希望最终结果的正确流程。 我正在摆弄 CodeCompiler 并在我设置的测试应用程序中生成 EXE。所以编译工作正常,我可以创建一个 hello world 等等,我也链接
我使用 CSharpCodeProvider 从 C# 编译 .net 代码并生成自定义 DLL。但我想在 DLL 中设置自定义属性,例如: File Description File Version
很抱歉这个问题很短,但我认为它不需要太多阐述。 使用 CSharpCodeProvider 是否会导致任何安全隐患,它是否会打开服务器进行攻击? 最佳答案 这取决于你如何使用它。以下是从安全使用到您肯
CompileAssemblyFromDom 是否比 CompileAssemblyFromSource 快? 它应该因为它可能会绕过编译器前端。 最佳答案 CompileAssemblyFromDo
我正在使用 CodeDom 创建新的 .cs 文件,稍后想使用 CSharpCodeProvider 编译/运行它们,但在引用方面遇到了一些问题。 代码如下: var provider
我在这里有点新,这是我的第一个问题。所以当我做错事时请不要对我发火(: 我的问题:我试图在运行时编译 C# 源代码,使用 CSharpCodeProvider . 除非我使用以下方法将 Compile
我有一个解决方案,其中包含 c# 项目、一些 netstandard 2.0 和其他 .net4.7。启动项目当然是net47。 在某一时刻,该项目使用 CodeDom 创建代码,并使用 CSharp
我有一个 CSharpCodeProvider,它接受一个类的代码。在编译代码的项目中,我有一个接口(interface)。我希望我正在编译的代码符合这个接口(interface)。 这是我能想到的最
我试图将动态编译与标准编译进行比较。而且动态编译好像慢了很多。根据我的基准测试,慢了 1400%。 下面是生成调用动态编译代码的委托(delegate)的方法: public static Funct
我正在寻找 CSharpCodeProvider.Parse 的替代方案。该方法应该解析 [C#] 代码源并返回一个 CompileUnit 对象。但是,该方法未在任何 .Net 框架中实现。 我的目
是否可以使用 CSharpCodeProvider 编译多个外部文件?我现在只是编译一个字符串。我想创建一个 .cs 文件的层次结构,然后编译它们。 谢谢。 最佳答案 使用 FromFileBatch
试图找出如何利用 CSharpCodeProvider 在运行时编译字符串数据。 在 xml 中,我将相当于存储在字符串中的谓词条件。 我希望能够在当前上下文中执行并获取这些语句的结果。 例如当 Va
我使用CSharpCodeProvider在内存中编译生成了一个新的命名空间,仅供临时使用。但是这个命名空间应该在一段时间后从内存中删除,以允许下一个生成的代码覆盖所有生成的类和方法的相同标识符。 最
我使用 CSharpCodeProvider 为我的应用编译即时插件。 现在可以尝试编译一个文件,它看起来不错,但会产生很多错误,例如 C# 代码与二进制文件粘在一起。有许多字符被处理为 error
我正在使用 CSharpCodeProvider 类来编译我在应用程序中用作 DSL 的 C# 脚本。当有警告但没有错误时,生成的 CompilerResults 实例的 Errors 属性不包含任何
我已成功使用本教程:http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime为 C# 代码的运行时编译和执行设置一
我有一个应用程序使用一些代码脚本在运行时生成 dll 并根据需要调用它们,但在我继续编写代码之前遇到了一些问题! 是否可以在不需要时从内存中卸载它们?如果不是 - 将它们加载到单独的应用程序域并使用一
我有一些 C# 代码可以从 SOAP WSDL 和 Swagger 文档动态生成源代码,然后使用 CSharpCodeProvider 类的 CompileAssemblyFromSource 方法对
我是一名优秀的程序员,十分优秀!