为什么C#在AppDomain中调用函数比VB快得多

为什么C#在AppDomain中调用函数比VB快得多,c#,.net,vb.net,appdomain,C#,.net,Vb.net,Appdomain,我创建了一个AppDomain沙盒,允许用户从父应用程序(用VB编写)运行自己的代码(C#或VB)。我提取了基本代码并创建了两个相同的应用程序,一个在VB中,另一个在C#中 我惊讶地发现C版本的运行速度至少快了60倍 我在StackOverflow或Google上找不到任何关于这种行为的参考资料。VB序列化Invoke调用的方式是否存在严重的低效 以下是正在执行的类型的VB代码: Imports System.Reflection Namespace UserCode Namespace

我创建了一个AppDomain沙盒,允许用户从父应用程序(用VB编写)运行自己的代码(C#或VB)。我提取了基本代码并创建了两个相同的应用程序,一个在VB中,另一个在C#中


我惊讶地发现C版本的运行速度至少快了60倍

我在StackOverflow或Google上找不到任何关于这种行为的参考资料。VB序列化
Invoke
调用的方式是否存在严重的低效

以下是正在执行的类型的VB代码:

Imports System.Reflection

Namespace UserCode
  Namespace Runtime

    Public Class Execute
      Inherits MarshalByRefObject

      Private _MethodInfo As MethodInfo

      Sub New()

        _MethodInfo = Nothing

      End Sub

      Public Sub SetAssembly(assemblyName As String, functionName As String)

        _MethodInfo = Nothing

        If assemblyName <> "" Then

          Dim assembly As Assembly = AppDomain.CurrentDomain.Load(assemblyName)
          Dim type As Type = assembly.GetType("CompiledUserCode")

          _MethodInfo = type.GetMethod(functionName, BindingFlags.Public Or BindingFlags.Static)

        End If

      End Sub

      Public Function ExecuteFunction(args() As Object) As Object

        Return _MethodInfo.Invoke(Nothing, args)

      End Function

    End Class

  End Namespace
End Namespace
以下是VB IL(构造函数+执行):

以下是C#IL:

我能看到的唯一显著区别是:

.maxstack 3
        .locals init (
            [0] object ExecuteFunction
        )
目前,如果我希望利用C#speed,我唯一的选择就是创建一个单独的C#程序集,其中包含沙盒代码。这60倍实际上是低估了。通过调用
ExecuteFunction
函数,可以简单地测量它:

object[] objects = new object[] { 1.0, 1.0, 1.0 };
作为参数和变量
对象[0]
,以防止任何优化(100000个循环)

在沙箱中实际运行的代码非常简单:

public static double StressFactor(double useStress, double stress, double p)
           {
           return useStress*stress+p;
           }
在重新测量速度差时,C#中的速度差快了近41倍。

经过(相当)几个小时的调查,我认为问题是由VB给幕后课程额外的“装饰”造成的

如果你在VB中检查一个简单的类,它比等价的C#类(例如Binder…/声明的…)有更多的属性等。这甚至适用于VB中实例化的C#类。此外,性能分析器显示,在VB中,反序列化/序列化索赔实体占用了相当大的时间。在C#中没有这种迹象。我再次猜测这是给VB类的额外“装饰”

检查了一下,发现没有办法去掉这些多余的东西


因此,我唯一的解决方案是在一个单独的C#dll中实现沙盒代码。

VB和C#在许多方面几乎(但不是完全)相同。没有理由期望任何重大的性能差异。我怀疑你的“完全相同”的应用程序并不像你期望的那样完全相同。我惊讶地发现帖子中没有代码。在这一点上,人们只能猜测你做错了什么……即使你的陈述是正确的,你也需要在这里放一些代码来证明它,告诉60倍的速度是从哪里来的,这样其他人就可以讨论它了。看看IL,看看?
\u MethodInfo.Invoke(Nothing,args)
\u MethodInfo.Invoke(this,args)在逻辑上不相同。如果在VB版本中使用
\u MethodInfo.Invoke(Me,args)
会发生什么?这是有道理的除此之外,C#还有一个优化编译器(如果您启用了优化,这是发布模式中的默认设置);我认为DirectX团队在过去一段时间做了一些基准测试,显示C++的运行速度相当于C++的97%。因此,如果速度很重要,您肯定希望在VB.NET上使用C。:-)
.maxstack 3
        .locals init (
            [0] object ExecuteFunction
        )
object[] objects = new object[] { 1.0, 1.0, 1.0 };
public static double StressFactor(double useStress, double stress, double p)
           {
           return useStress*stress+p;
           }