为什么params'性能较差'比常规阵列?

时间:2015-07-19 00:04:50

标签: c# params variadic-functions

如果你现在就在你的IDE中键入SELECT *, COUNT(col_1) AS freq FROM mytable WHERE col_2 = x GROUP BY col_1 ORDER BY freq DESC ,你会发现有4种不同的重载:一种是带字符串和一个对象,另一种是带字符串和两个对象,然后是一个三个对象,最后一个使用string.Format。根据{{​​3}},这是因为params会产生“开销”,而其他一些语言可能不会支持它。

我的问题是,为什么不能像这样调用方法:

params

在编译时基本上转换为

void Foo()
{
    Bar(1, 2, 3);
}

void Bar(params int[] args)
{
    // use args...
}

?然后它不会创建除数组创建之外的任何开销(无论如何都是必需的),并且与其他语言完全兼容。

参数的数量在编译时已经知道,那么是什么阻止C#编译器进行某种字符串替换并使第一个场景基本上是语法糖?为什么我们必须专门实现this answer以支持可变参数?

1 个答案:

答案 0 :(得分:3)

标题做出了错误的假设。

params和non-params方法都采用数组;区别在于编译器在进行params方法调用时会发出IL来隐式创建数组。 数组作为单个参数传递给两个方法

can be seen in this .NET Fiddle(查看"整理 - >查看IL")。

using System;

public class Program
{
    public static void Main()
    {
        var a1 = 1;
        var a2 = 2;
        var a3 = 3; 
        with_params(a1,a2,a3);
        no_params(new [] {a1,a2,a3});
    }

    public static void with_params(params int[] x) {}
    public static void no_params(int[] x) {}
}

两种情况下 IL都是相同的;创建一个新数组,填充它,并将数组提供给调用的方法。

有一个"例外"对于这个相同的IL生成,编译器可以在非参数形式中使用时移出常量值数组,并使用' dup'初始化,as seen here。但是,在两种情况下都提供 new 数组作为参数。