传递引用参数与包装器类型的长列表

Posted

技术标签:

【中文标题】传递引用参数与包装器类型的长列表【英文标题】:Long lists of pass-by-ref parameters versus wrapper types 【发布时间】:2010-11-18 18:58:07 【问题描述】:

我需要从一个函数中取出三个对象,我的直觉是创建一个新类型来返回三个引用。或者,如果参考是相同的类型,我可以使用一个数组。但是通过引用更容易:


        private void Mutate_AddNode_GetGenes(ref NeuronGene newNeuronGene, ref ConnectionGene newConnectionGene1, ref ConnectionGene newConnectionGene2)
        

        

这显然没有错,但我犹豫是否使用这种方法,主要是出于美学和心理偏见的原因。实际上是否有充分的理由使用其中一种方法而不是其他方法?创建额外的包装器对象或将参数推送到堆栈上可能存在性能问题。请注意,在我的特定情况下,这是 CPU 密集型代码。 CPU 周期很重要。

有没有更优雅的 C#2 的 C#3 方法?

谢谢。

【问题讨论】:

【参考方案1】:

担心这两个选项的相对执行速度可能是过早的优化。专注于首先让算法正确,并拥有干净、可维护的代码。完成后,您可以在其上运行分析器并优化占用 80% CPU 时间的 20% 代码。即使这个方法最终在 20% 之内,两种调用方式之间的差异也可能很小。

所以,抛开性能问题不谈,我可能会使用容器类。由于这个方法只接受这三个参数,并且(可能)修改了每个参数,因此将它作为容器类的方法听起来很有意义,它具有三个成员变量而不是 ref 参数。

【讨论】:

【参考方案2】:

如果您担心包装类型的性能(更简洁,恕我直言),您应该使用结构。 .NET 的当前 32 位实现(以及即将推出的 64 位 4.0)在许多情况下支持内联/优化结构,因此您可能会发现结构和 ref 参数之间没有任何性能差异。

【讨论】:

【参考方案3】:

对于几乎所有的计算问题,您不会注意到 CPU 差异。由于您的示例代码中包含“基因”一词,因此您实际上可能属于罕见的代码类别。

创建和销毁对象只是为了包装其他对象会消耗一些性能(毕竟它们需要被创建和垃圾收集)。

从美学上讲,我不会创建一个对象只是为了将不相关的对象分组,但如果它们在逻辑上属于一起,那么定义一个包含对象是完全可以的。

【讨论】:

PS - 与管理堆中的数据相比,管理堆栈中的数据非常有效。 @Eric,你为什么不把这个评论放在你的答案中? 因为事后添加评论更快?我不知道是否有理由编辑答案而不是发表评论?

以上是关于传递引用参数与包装器类型的长列表的主要内容,如果未能解决你的问题,请参考以下文章

PHP:通过引用的可变长度参数列表?

C#在方法调用中,参数按值传递与按引用传递的区别是啥?

js 函数参数传递引用类型与基本类型

JAVA 值传递与引用传递的几种情况

java中String包装类枚举类的引用传递

基本类型包装类型引用类型String等作为实参传递后值会不会改变?