代码之家  ›  专栏  ›  技术社区  ›  Carlo V. Dango

在C中使用参数的成本#

  •  19
  • Carlo V. Dango  · 技术社区  · 14 年前

    是否有人建议使用C中的参数来传递方法参数?我正在考虑对前6个参数进行重载,然后使用params功能对第7个参数进行重载。我的理由是避免参数特性所需的额外数组分配。这适用于一些高性能的实用方法。有什么建议吗?创建所有重载是浪费代码吗?

    6 回复  |  直到 7 年前
        1
  •  53
  •   Dan Tao    14 年前

    老实说,我有点被大家喊“过早优化”的声音困扰了。这就是原因。

    1. 你说的话很有道理, 尤其 正如您已经指出的,您正在开发一个高性能的库。
    2. 甚至bcl类也遵循这种模式。考虑所有的重载 string.Format Console.WriteLine .
    3. 这是 很容易纠正 . 运动背后的整个前提 反对 过早的优化是当你做一些事情的时候 狡猾的 为了优化性能,您可能会意外地破坏某些东西,并降低代码的可维护性。我看不出这有多危险;你所做的,对你自己以及任何未来可能处理你的代码的开发人员都应该是非常直接的。

    而且,即使你 异形的 两种方法的结果在速度上相差很小,仍然存在内存分配的问题。为每个方法调用创建一个新数组需要分配更多的内存,这些内存稍后需要进行垃圾收集。在一些需要“接近”实时行为的场景中(如算法交易、现场 我是 在中),最小化垃圾收集与最大化执行速度同样重要。

    所以,即使它给我赢得了一些选票:我说去争取它。

    (对于那些声称“编译器肯定已经做了这样的事情”的人来说,——我不太确定。首先,如果是这样的话,我不明白为什么BCL类会遵循这个模式,正如我已经提到的那样。但更重要的是,接受 多个参数 一个接受 数组 . 只是因为一个 可以 被用作另一个的替代品并不意味着编译器会,或者 应该 ,尝试这样的替换)。

        2
  •  15
  •   Hans Passant    7 年前

    是的,这是.NET框架使用的策略。string.concat()就是一个很好的例子。它有最多4个字符串的重载,加上一个采用params string[]的回退字符串。非常重要的是,concat需要快速,当用户使用+运算符而不是stringbuilder时,它可以帮助用户陷入成功的深渊。

    你将得到的代码复制就是代价。你可以对它们进行分析,看看加速是否值得维护。

    fwiw:在.NET框架中有很多这样的微优化。有点必要,因为设计者不能真正预测他们的类将如何使用。string.concat()很可能用于对程序性能至关重要的紧密内部循环,例如,在启动时只运行一次的配置阅读器。作为您自己代码的最终用户,您通常可以不必担心这一点。反过来也一样,当.NET框架代码的好处不太可能被衡量时,它明显地没有微优化。就像在核心代码很慢的时候提供重载。

        3
  •  4
  •   Oded    14 年前

    你总是可以通过 Tuple 作为参数,或者如果参数的类型始终相同,则 IList<T> .

    正如其他答案和评论所说,只有在以下情况下才能进行优化:

    1. 确保行为正确。
    2. 确定 需要 优化。
        4
  •  2
  •   Iravanchi    14 年前

    我的观点是,如果您的方法能够获得无限数量的参数,那么它内部的逻辑以数组样式工作。因此,对有限数量的参数进行重载不会有帮助。除非,您可以以一种完全不同的方式实现有限数量的参数,这要快得多。

    例如,如果您要将参数传递给console.writeline,那么其中也有一个隐藏的数组创建,因此无论哪种方式,您最终都会得到一个数组。

    而且,很抱歉打扰到丹涛,我也觉得这是过早的优化。因为您需要知道使用有限数量的参数进行重载会有什么不同。如果您的应用程序的性能非常关键,那么您需要实现这两种方法,并尝试运行测试并比较执行时间。

        5
  •  1
  •   egrunin    14 年前

    在这个阶段甚至不要考虑表演。创建任何重载都将使您的代码更容易编写,两年后的凌晨4点更容易理解。有时这意味着参数,有时这意味着避免它。

    在你得到了一些有用的东西之后,找出这些是否是性能问题。做参数并不难 更多 复杂,但如果你现在增加不必要的复杂度,你就永远不会做到。 较少的 所以以后。

        6
  •  1
  •   Rei Miyasaka    14 年前

    你可以试试 this 对性能进行基准测试,这样您就有了一些具体的数字来做决定。

    一般来说,对象分配比C/C++中略微快一些,删除很快,对于小对象来说要快得多,直到每秒有成千上万个对象。这是一个旧的 article regarding memory allocation performance .

    推荐文章