C# 重载或可选参数之间的性能差异?

C# 重载或可选参数之间的性能差异?,c#,performance,overloading,optional-parameters,C#,Performance,Overloading,Optional Parameters,我想知道我是否应该在C#中使用可选参数。直到现在,我总是重载方法。但是可选参数也很好,更干净,代码更少。我在其他语言中使用它们,所以我在某种程度上也习惯了它们。有什么东西反对使用它们吗?对我来说,表现是第一个关键点。它会掉下来吗? 示例代码: class Program { // overloading private static void test1(string text1) { Console.WriteLine(text1 + " " + "w

我想知道我是否应该在C#中使用可选参数。直到现在,我总是重载方法。但是可选参数也很好,更干净,代码更少。我在其他语言中使用它们,所以我在某种程度上也习惯了它们。有什么东西反对使用它们吗?对我来说,表现是第一个关键点。它会掉下来吗?
示例代码:

class Program
{
    // overloading
    private static void test1(string text1)
    {
        Console.WriteLine(text1 + " " + "world");
    }

    private static void test1(string text1, string text2)
    {
        Console.WriteLine(text1 + " " + text2);
    }

    // optional parameters
    private static void test2(string text1, string text2 = "world")
    {
        Console.WriteLine(text1 + " " + text2);
    }

    static void Main(string[] args)
    {
        test1("hello");
        test1("hello", "guest");

        test2("hello"); // transforms to test2("hello", "world"); ?
        test2("hello", "guest");

        Console.ReadKey();
    }
}

我测量了数百万重载调用和可选参数调用所需的时间

  • 带字符串的可选参数:18%较慢(2个参数,释放)

  • 带int的可选参数:我刚刚做了一个快速测试,编译器优化了代码。这个基本的例子是主要的方法

    public static void OptionalParamMethod(bool input, string input2 = null)
    {
    }
    
    public static void Main(string[] args)
    {
        OptionalParamMethod(true);
        OptionalParamMethod(false, "hello");
    }
    
    编译为该值,以便编译器填写可选参数

    public static void Main(string[] args)
    {
        OptionalParamMethod(true, null);
        OptionalParamMethod(false, "hello");
    }
    
    至于性能,您可能会认为可选参数有一点优势,因为只有一个方法调用,而不是像重载方法那样的链式方法调用。下面的代码是编译输出,以显示我所说的内容。这是一个相当学术性的问题,我怀疑你在实践中是否会注意到

    public static void Main(string[] args)
    {
        OptionalParamMethod(true, null);
        OptionalParamMethod(false, "hello");
        OverloadParamMethod(true);
        OverloadParamMethod(false, "hello");
    }
    
    public static void OptionalParamMethod(bool input, [Optional, DefaultParameterValue(null)] string input2)
    {
        Console.WriteLine("OptionalParamMethod");
    }
    
    public static void OverloadParamMethod(bool input)
    {
        OverloadParamMethod(input, null);
    }
    
    public static void OverloadParamMethod(bool input, string input2)
    {
        Console.WriteLine("OverloadParamMethod");
    }
    

    重载或可选参数本身都不会导致性能发生任何变化。正如David Ewen所指出的,C#编译器生成的IL不知道可选参数(这是一些版本控制错误的来源,这些错误来自可以是文本的类型上的可选参数)

    至于超载。C#是一种(大部分)静态类型语言。编译后的代码直接引用相应方法的地址。当在编译时重载时,会对性能造成很小的影响。事实上,在C++中,重载是通过名为“MangFun”的过程来完成的,在编译过程中,每个编译时的重载都被赋予一个唯一的名称。 但是,在某些情况下,重载可能会影响性能。但这些是非常明显的,比如在反射期间和在动态类型代码中


    听起来您对虚拟/抽象函数的性能影响感到困惑。为了让.net运行时解析正确的函数,还有一个额外的步骤可以查找该方法的特定类型的实现。

    您能告诉我如何查看优化的代码吗?对我来说,这似乎是一个性能下降。它是?用于查看已编译的代码。它编译出来的性能下降与任何普通方法调用都不一样。PS这是一个调试版本,如果它是一个发布版本,那么编译器实际上会完全删除方法调用,因为该方法是一个NOP。但是当您使用1个参数调用重载方法时,会发送1个对象。当您使用2个参数调用可选的参数方法,并且优化的代码发送所有参数(默认值)时,会使用更多的堆栈空间,复制值和引用会花费更多的时间。只需在答案中添加更多。通常使用可选参数,在其中使用重载方法进行方法链接。如果这不是您想要实现的,那么您需要根据每个案例的优点进行评估,但一般来说,可选参数可能会赢得性能。-1由于过载或可选参数(在运行时),没有性能影响。关于过载的性能问题的答案可能重复