Problems with params array?

Tags: .NET

I noticed today that the ever-popular String.Format() method has several overloads - in addition to the Format(string format, params object[] args) overload I was expecting, it seems there are three special-case overloads for one, two or three parameters. A glance with Reflector shows that these three overloads simply instantiate a new object[] with the given args and pass them on to the main overload.

Does anyone have any idea why it's doing that? Is there some sort of performance penalty involved with using params array that the BCL team decided to bypass by special-casing the most common instances?

I was given to understand that that params token is a compile-time only feature of the C# language, and shouldn't have any effect after compilation.

Interesting.

7 Comments

  • Thomas Tomiczek said

    ::Does anyone have any idea why it's doing that? Yes, and IIRC that is documented. ::Is there some sort of performance penalty ::involved with using params array that the ::BCL team decided to bypass by special-casing ::the most common instances? Yes. Having an array is overhead. Casting to and from a generic type (object) is overhead. ::I was given to understand that that params ::token is a compile-time only feature of the ::C# language, By whom? It goes down into an array of X. Access to elements of an array - setting and getting - is always slower. So the .NET team decided that for smaller numbers the system will provide overloads and use them if there. Now, that said the Format team obviously decided to just bypass that and then fall back to the same method :-) Which sort of is pointless as it means that there are no savings at all.

  • AvnerK said

    Your explanation doesn't make sense. There's no benefit to special-casing a set number of parameters if you're just pushing that back into an array. I was asking about any overhead for using a params array, not just any array. I also didn't understand your reference about casting to a generic object type - while true, it's not really what I was talking about. My question was specifically about the params array type and the reason the string.Format() writer decided to bypass for common cases. Not about arrays, just about variable-length params arrays. And I still believe the params array construct is language-dependent. Looking at the IL it looks like the signature is identical to that of a normal array, but the compiler added a System.ParamArrayAttribute to it.

  • Thomas Tomiczek said

    ::There's no benefit to special-casing a set ::number of parameters if you're just pushing ::that back into an array. But that is something that the class does, not what the .net runtime does. It is generally adviced to profivde overlaods for 1-2 parameters and THEN go to params array. BUT: If all your overloads do is generate the params array, then this is NOT the problem of the specs. Example: An ADD method.... Could provide overloads for 1, 2, 3 parameters.... ...and then one taking a params array adding all entries there. Now... ...if this methods actually implements methods for the overloads, there is a speed benefit. if the implementation just creates an array and forwards the call - then that is a senseless implementation. ::And I still believe the params array ::construct is language-dependent. Looking at ::the IL it looks like the signature is ::identical to that of a normal array, but the ::compiler added a System.ParamArrayAttribute ::to it. Given that the ParamArrayAttribute is defined in System and HAS to be supported by the langauge compilers, basically, it is not a choice of the language. As such, it is not a language feature. It is a requirement. WIth the same logic you could say that support for a lot of other things is optional - it is not.

  • AvnerK said

    (I'm stealing your :: convention - it's cool) :: But that is something that the class does, :: not what the .net runtime does. That's why I originally asked why the BCL team chose to do so - the Base Class Library team who wrote the base classes like String. :: It is generally adviced to profide :: overlaods for 1-2 parameters and THEN :: go to params array. Why? Just to avoid using arrays? I can understand such fine optimization in commonly used commands (like string.Format()) but I wasn't familiar with a general recommendation for this. :: if the implementation just creates an :: array and forwards the call - then that :: is a senseless implementation. I agree, which is why I asked the question in the first place. :: Given that the ParamArrayAttribute is :: defined in System and HAS to be supported :: by the langauge compilers, basically, it is :: not a choice of the language. As such, it :: is not a language feature. It is a :: requirement. This is an entirely different question, and here I disagree with you. I'll open this in a new entry, by your leave. Too cramped in here.

  • Wesner Moise said

    Think "Common Language Runtime" You have a C# centric view. The .NET framework is meant to be easily supported all languages that use the CLR, including languages that do not support parameter arrays! A decision that is suboptimal for C# may be more optimal for the framework.

  • AvnerK said

    Ok, that's an answer I can understand and support. While C# and VB users have no need for these overloads, I can see why users of other languages can find them much easier to use than the full-blown object[] overload. Thanks.

  • Joe said

    > ... that's an answer I can understand and support It does seem the most reasonable explanation. But it's a bit tough for users of these non-mainstream languages that FxCop will give a SpecifyIFormatProvider warning when they use these overloads. Why aren't there similar overloads that take an IFormatProvider parameter?

Comments have been disabled for this content.