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

时间:2013-10-25 06:47:31

标签: c# performance overloading optional-parameters

不,没有回答↑

我想知道我是否应该在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个参数,发布)
  • 带有整数的可选参数:&lt; 1%更快(2个参数,发布)

(也许编译器优化或将来优化这些可选参数调用?)

2 个答案:

答案 0 :(得分:3)

我刚做了一个快速测试,编译器优化了代码。这个基本的例子是Main方法。

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");
}

至于性能,您可以认为可选参数有一点点优势,因为只有一个方法调用而不是像通常对重载方法那样的链式方法调用。下面的代码是编译输出,以显示我在说什么。 difference虽然很有学术性,但我怀疑你在实践中会注意到它。

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");
}

答案 1 :(得分:2)

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

至于重载。 C#是(大多数)静态类型语言。编译后的代码直接引用相应方法的地址。超载AT COMPILE时,性能会有轻微影响。事实上,在C ++中,重载由一个名为“name mangling”的进程完成,其中编译时的每个重载都被赋予一个唯一的名称。

但是,有些情况下CAN会影响性能。但这些非常明显,例如在反射和动态类型代码中。

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