简体   繁体   English

方法参数的C#效率

[英]C# Efficiency for method parameters

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. 我之所以想使用它,是因为已经有大约30个参数传递给该方法,并且我觉得继续添加更多参数变得越来越混乱。 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. 我正在研究现有的代码,不在我的项目范围内,花时间重新设计该方法以减少传递给该方法的参数数量,但是我认为了解此更改的含义将是一种很好的做法。

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%." “程序员浪费大量时间来思考或担心程序非关键部分的速度,而这些效率的尝试实际上在考虑调试和维护时会产生严重的负面影响。我们应该忘记效率低下,例如, 97%的时间:过早的优化是万恶之源,但我们不应该在这3%的临界风险中放弃机会。”

In terms of productivity, parameters > arrays . 在生产率方面, 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! 每个人都应该知道,唐纳德·克努斯(Donald Knuth)在1974年曾说过。在此声明发表40多年之后,我们仍然经常会过早地进行优化 (甚至是毫无意义的优化 )!

Further reading 进一步阅读

I would take a look at this other Q&A on Software Engineering 我会看一下有关软件工程的其他问答

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. 众所周知,热路径代码可以通过击中params来提供重载,而重载需要使用一定数量的单个参数,但实际上仅在热路径上有所不同。 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. 隔离的更改在性能方面具有非隔离的影响,因此,如果范围更广的上下文意味着调用A的代码比B慢,那么Internet上的人是否告诉您A的速度比B的速度还快。 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. 比起做一堆奇怪的事情的代码,更自然的代码在需要时更容易调整性能。

Third way would be use of params , Params - MSDN 第三种方法是使用paramsparams-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 array []尽管继承了实现IEnumerableIEnumerable<t>ICloneableIListICollectionICollectionIEnumerableIStructuralComparableIStructuralEquatable )的抽象Array类,这意味着对象比三个值类型的Parameters更容易被炸毁,这显然会使速度变慢阵列-MSDN

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. 可用性:如果要发送类似参数的列表,则必须使用数组或列表,如果它只是碰巧属于同一类型的几个参数,则应分别发送它们。

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? 为什么要使用params关键字?

public static void MethodName{params bool [] boolAarray}
{
    //extract data here
}

Agreed with Matias' answer. 同意Matias的回答。

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... 同样,如果您想让其他开发人员(作为API的一部分,无论是公共的还是私有的)都可以使用此方法,则intellisense根本无法帮助他们设置应该设置的参数...

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... 它将很好地显示给其他人...

I would take a different approach and use Flags; 我将采用另一种方法并使用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 检查http://rextester.com/QRFL3116 Jamiec注释中添加的方法

  • M1 took 5ms M1花了5毫秒
  • M2 took 23ms M2花了23毫秒
  • M3 took 4ms M3花了4毫秒

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM