0

Am I correct in saying that this:

public static void MethodName{bool first, bool second, bool third}
{
   //Do something
}

Is more efficient than this:

public static void MethodName{bool [] boolArray}
{
    bool first = boolArray[0]; 
    bool second = boolArray[1];
    bool third = boolArray[2];
    //Do something
}

My thoughts are that for both they would have to declare first, second and third - just in different places. But for the second one it has to add it into an array and then unpack it again.

Unless you declared the array like this:

MethodName(new[] { true, true, true });

In which case I am not sure which is faster?

I ask because I am thinking of using the second one but wanted to know if/what the implications are on performance.

In this case performance is not particularly important, but it would be helpful for me to clarify this point.

Also, the second one has the advantage that you can pass as many values as you like to it, and it is also easier to read I think?

The reason I am thinking of using this is because there are already about 30 parameters being passed into the method and I feel it is becoming confusing to keep adding more. All these bools are closely related so I thought it may make the code more manageable to package them up.

I am working on existing code and it is not in my project scope to spend time reworking the method to decrease the number of parameters that are passed into the method, but I thought it would be good practice to understand the implications of this change.

Alex
  • 3,730
  • 9
  • 43
  • 94
  • 2
    Efficient how? More efficient in terms of time spent calling the different methods? More efficient in terms of memory used for the parameters? More efficient in terms of time having to debug such a method (ie. development time)? – Lasse V. Karlsen Nov 25 '16 at 11:38
  • why not go with `MethodName(params bool[] bools)` and then you could call it either way! In any case the perf difference will be negligable – Jamiec Nov 25 '16 at 11:38
  • 1
    There is likely no noticeable performance change, even when doing a huge number of operations. If you want to "*pass as many values as you like*" It is worth looking into the `params` keyword also [see here](https://msdn.microsoft.com/en-us/library/w5zay9db.aspx) – Alfie Goodacre Nov 25 '16 at 11:38
  • 1
    @LasseV.Karlsen did you read the full question, OP goes on to explain the question is regarding performance – Alfie Goodacre Nov 25 '16 at 11:39
  • 1
    I would go with the first option since the second option requires an object around the 3 bool values. If you know that you will always pass 3 bool's, never less, never more, and the meaning is "first", "second" and "third", then I would definitely go with the named specific parameters. If you instead wish to process "a collection of bools", use something else (maybe not even then an array but IEnumerable or something). – Lasse V. Karlsen Nov 25 '16 at 11:40
  • I would take a different approach and use Flags; public static void MethodName(int Flag) { if (Flag & FIRST) { } } Chances are the compiler will do its own optimisations – Ol1v3r Nov 25 '16 at 11:40
  • @AlfieGoodacre "Performance" is also a nonspecific term. Both memory usage and cpu time usage is inside the performance topic. – Lasse V. Karlsen Nov 25 '16 at 11:40
  • 2
    _In which case I am not sure which is faster?_ - run both methods and compare which is faster – Fabio Nov 25 '16 at 11:41
  • 1
    Don´t do such micro-optimization unless you know you really have to. Consider your *actual* problems by asking a profiler such as DotTrace for your performance-bottlenecks- *if* they even exist. See also: [Which horse runs faster](https://ericlippert.com/2012/12/17/performance-rant) – MakePeaceGreatAgain Nov 25 '16 at 11:41
  • 2
    Over simplistic performance analysis - there is very little difference: http://rextester.com/ZWNB22061 Add a single database call in somewhere and this will not be your bottleneck in a million years. – Jamiec Nov 25 '16 at 11:44
  • 2
    I've added an answer, but StackOverflow should add a new kind of close vote that should contain this title: **Premature optimization is the root of all evil**. LOL – Matías Fidemraizer Nov 25 '16 at 11:45
  • I suppose it´s also not within the scope of ypur project to do such kind of un-neccessary optimization. Focus on your actual work instead of nano-seconds and CPU-cycles. In particular focus on code-mantainability. That means allwqys ensure your code stays maintanable, easy to understand **and working**. Quite often we break code by doing optimization. – MakePeaceGreatAgain Nov 25 '16 at 11:57

7 Answers7

10

In terms of performance, there's just an answer for your question:

"Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%."

In terms of productivity, parameters > arrays.

Side note

Everyone should know that that was said by Donald Knuth in 1974. More than 40 years after this statement, we still fall on premature optimization (or even pointless optimization) very often!

Further reading

I would take a look at this other Q&A on Software Engineering

Community
  • 1
  • 1
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • 1
    True, but Knuth wrote that in an article about how he was quite happy to use `goto` despite Dijkstra's recent "Go To Considered Harmful" when it made a function 13% faster. The piece as a whole is strongly in favour of making things more performant, the advice quoted solely about when and where to do so. While the OP says it's not important in a given case, the question as a whole could be relevant to a case where it really is. It's not premature after you've realised you do need it. – Jon Hanna Nov 25 '16 at 11:54
  • @JonHanna But you know that it's impossible that you would need to avoid parameters over arrays in the 99.999999999% of the cases.... – Matías Fidemraizer Nov 25 '16 at 11:56
  • @JonHanna Obviously times have changed since Knuth wrote that. Probably someone like him wouldn't write an article, book or whatever to defend `goto` in 2016. But I doubt that an optimization article would talk about using arrays over parameters.... For me, it should be a compiler optimization rather than dealing with such optimization in a high-level language. – Matías Fidemraizer Nov 25 '16 at 11:59
  • I understand that he still stands by his defence of `goto` (and I still agree). But these days separate parameters vs. single array parameters is indeed something touched on in performance work when it *does* matter. The framework overloads that offer multiple parameters alongside `params` arrays exist for this reason. (And quite a few tweaks to the framework code have been done to make sure the former rather than the latter is called, purely for the performance impact). – Jon Hanna Nov 25 '16 at 12:06
4

Am I correct in saying that this: Is more efficient than this:

In isolation, yes. Unless the caller already has that array, in which case the second is the same or even (for larger argument types or more arguments) minutely faster.

I ask because I am thinking of using the second one but wanted to know if/what the implications are on performance.

Why are you thinking about the second one? If it is more natural at the point of the call then the reasons making it more natural are likely going to also have a performance impact that makes the second the better one in the wider context that outweighs this.

If you're starting off with three separate bools and you're wrapping them just to unwrap them again then I don't see what this offers in practice except for more typing.

So your reason for considering this at all is the more important thing here.

In this case performance is not particularly important

Then really don't worry about it. It's certainly known for hot-path code that hits params to offer overloads that take set numbers of individual parameters, but it really does only make a difference in hot paths. If you aren't in a hot path the lifetime saving of computing time of picking whichever of the two is indeed more efficient is unlikely to add up to the amount of time it took you to write your post here.

If you are in a hot path and really need to shave off every nanosecond you can because you're looping so much that it will add up to something real, then you have to measure. Isolated changes have non-isolated effects when it comes to performance, so it doesn't matter whether the people on the Internet tell you A is faster than B if the wider context means the code calling A is slower than B. Measure. Measurement number one is "can I even notice?", if the answer to that measurement is "no" then leave it alone and find somewhere where the performance impact is noticeable to optimise instead.

Write "natural" code to start with, before seeing if little tweaks can have a performance impact in the bits that are actually hurting you. This isn't just because of the importance of readability and so on, but also because:

  1. The more "natural" code in a given language very often is the more efficient. Even if you think it can't be, it's more likely to benefit from some compiler optimisation behind the scenes.
  2. The more "natural" code is a lot easier to tweak for performance when it is necessary than code doing a bunch of strange things.
Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • The reason I am thinking of using this is because there are alreadyabout 30 paramers being passed into the method and I feel it is becoming confusing to keep adding more. All these bools are closely related so I thought it may make the code more manageable to package them up – Alex Nov 25 '16 at 11:51
  • 2
    @Alex Then you don´t have a performance-problem but a design-problem as your method (and your class also maybe) does way too much. Allways cosider the Single-responibility-principle. – MakePeaceGreatAgain Nov 25 '16 at 11:51
  • 3
    `30` would be different to `3` here if this was a fast-path case and performance really did matter, but again you'd have to measure because whichever wins in isolation won't necessarily win in the wider context (and include the time spent building the array in your measurement). As @HimBromBeere says you have a design problem and maybe need to use a different approach. A `[Flags]` enum could just fit 30 boolean values (32, one based on `long` another 32 again) and might be easier to use. At the very least calling with named parameters might make the calls more readable:... – Jon Hanna Nov 25 '16 at 12:00
  • 1
    ... `MethodName(true, false, false, true…` is harder to read with many bools than `MethodName(dummyRun: true, recordProgress: false, …` or whatever. – Jon Hanna Nov 25 '16 at 12:01
  • Consider creating a structure and group the parameters inside this structure? passing a ref to the structure down. I agree with HimBromBeere that you should consider splitting up the class and opt for a better design, but In real life this is not always allowed/possible to do – Ol1v3r Nov 25 '16 at 12:06
1

Third way would be use of params, Params - MSDN

In the end I dont think it will change much in performance.

array[] though inheritates from abstract Array class which implements IEnumerable and IEnumerable<t> (ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable), this means objects are more blown up than three value type Parameters, which will make then slower obviously Array - MSDN

TripleEEE
  • 499
  • 3
  • 11
  • ;) I never said it will make your application run faster in any way anyone of us might notice, but still there is a difference. It's just a question of how often you call that function ;) I totaly agree with your answer above! – TripleEEE Nov 25 '16 at 11:52
  • Yeah, I was just saying that in irony mode ;P – Matías Fidemraizer Nov 25 '16 at 11:55
  • `params` is largely the same as the second way, with some added syntactic sugar. The fact that `bool[]` inherits from `Array` has zero impact on the size of arrays or on the performance of any operation done directly on it as `bool[]`. – Jon Hanna Nov 25 '16 at 11:56
  • @JonHanna you are right, there are no properties which are derived... I'd changed that. – TripleEEE Nov 25 '16 at 12:05
  • The fact that something inherits from something else impacts what can be reached from a single 64-bit (32-bit on 32-bit .NET) piece of memory that points into v tables and has no per-instance cost. – Jon Hanna Nov 25 '16 at 12:08
1

I don't think this would affect the performance of your app at all.

Personally

I'd go with the first option for two reasons:

  1. Naming each parameter: if the project is a large scale project and there is a lot of coding or for possible future edits and enhancements.
  2. Usability: if you are sending a list of similar parameters then you must use an array or a list, if it just a couple of parameters that happened to be of the same type then you should be sending them separately.
Community
  • 1
  • 1
Monir Tarabishi
  • 716
  • 1
  • 16
  • 30
0

You could test performance differences on both, but I doubt there would be much difference.

You have to consider maintainability, is another programmer, or even yourself going to understand why you did it that way in a few weeks, or a few months time when it's time for review? Is it easily extended, can you pass different object types through to your method?

If your passing a collection of items, then certainly packing them into an array would be quicker than specifying a new parameter for each additional item?

If you have to, you can do it that way, but have you considered param array??

Why use the params keyword?

public static void MethodName{params bool [] boolAarray}
{
    //extract data here
}
Community
  • 1
  • 1
Joey Bob
  • 312
  • 8
  • 21
0

Agreed with Matias' answer.

I also want to add that you need to add error checking, as you are passed an array, and nowhere is stated how many elements in your array you will receive. So you must first check that you have three elements in your array. This will balance the small perf gain that you may have earned.

Also, if you ever want to make this method available to other developers (as part of an API, public or private), intellisense will not help them at all in which parameters they're suppposed to set...

While using three parameters, you can do this :

///<summary>
///This method does something
///</summary>
///<param name="first">The first parameter</param>
///<param name="second">The second parameter</param>
///<param name="third">The third parameter</param>
public static void MethodName{bool first, bool second, bool third}
{
   //Do something
}

And it will be displayed nicely and helpfully to others...

Martin Verjans
  • 4,675
  • 1
  • 21
  • 48
0

I would take a different approach and use Flags;

public static void MethodName(int Flag) 
{ 
    if (Flag & FIRST) { } 
} 

Chances are the compiler will do its own optimizations;

Check http://rextester.com/QRFL3116 Added method from Jamiec comment

  • M1 took 5ms
  • M2 took 23ms
  • M3 took 4ms
Ol1v3r
  • 758
  • 1
  • 10
  • 23