1

我的问题来自Proper way of design functions with and without debug information in C++。我想比较以下功能的效率:

功能一

bool my_func1(int arg1, int &output, std::vector<int> &intermediate_vec);
  {
     // do something
  }

当我使用这个函数时,我会通过以下方式调用它:

int arg;
int output;
std::vector<int> intermediate_vec;
my_func1(arg,output,intermediate_vec);

功能二

  bool my_func2(int arg1, int &output);
  {

    std::vector<int> intermediate_vec
    return my_func1(arg1, output, intermediate_vec);
  }

当我使用这个函数时,我会通过以下方式调用它:

int arg;
int output;
my_func2(arg,output);

我的问题是:这两个功能是否具有相同的效率?

4

6 回答 6

2

这是需要详细回答才能准确回答的问题之一。

应该有很小的区别,特别是如果编译器能够内联func1func2避免额外的调用开销(也就是说,函数的声明方式使得编译器可以从调用代码中“看到”它们)。

唯一会存在较大差异的情况是您是否可以避免构造/破坏intermediate_vec- 例如,您在循环中重用相同的向量(但在这种情况下,您很可能会“重置”向量,这是主要的破坏向量的一部分)。

作为总时间的一部分,差异有多大,取决于实际do somethingfunc1做什么。

但是,与所有性能问题一样,值得有一个性能基准来比较两者。确保使用实际代码的优化级别对其进行编译。

于 2013-06-21T08:01:26.753 回答
1

这个问题真的很愚蠢。这真的取决于你的用途intermediate_vec。如果它是接口的一部分,则需要将其作为参数,并记录其前置条件和后置条件。如果它不是接口的一部分,那么将其作为参数会暴露不应暴露的函数内部。效率(除了程序员的效率)不包括在内。

除此之外,比较效率(至少在这种情况下)的唯一方法是测量。

最后,如果您在一个紧凑的、频繁执行的循环中调用该函数,并且分析器显示 intermediate_vec(在版本 2 中)的构造导致显着延迟,您可能会通过使用第一个版本并将实际向量移到环形; 向量可能会很快达到其最大容量,之后将不再有动态分配。但是这种改变只应该在绝对必要的情况下进行,当程序不够快时,并且分析器显示创建向量时的分配是造成这种情况的重要原因。我会强调你可能会; 很大程度上仍然取决于编译器如何优化以及如何std::vector实现。

于 2013-06-21T08:05:51.057 回答
1

您几乎无法仅从其签名中了解有关函数性能的任何信息。我可以用这些签名中的任何一个编写你能想象到的最快和最慢的函数。

在第二个选项中,您正在向函数添加第三个参数。你需要那个参数吗?如果需要,请使用该选项。如果没有,请使用第一个。

于 2013-06-21T07:56:26.527 回答
0

优化函数的行为通常是非常不可预测的。毕竟,您的所有函数都可能被内联并显示完全相同的性能特征。它们可能没有被内联,或者在任何一种情况下某些优化都可能失败,并且任何情况下的性能都可能更差。认真解决此类问题的唯一方法是使用可靠的分析器在不同设置下测量性能。

于 2013-06-21T08:03:04.747 回答
0

测量 cpu 时钟时间以进行实际测量

于 2013-06-21T07:58:34.757 回答
0

由于您将向量作为参考传递(而不是创建临时副本),因此任何性能差异都可以忽略不计(编译器甚至可能将其内联到等效的东西 - 如果不是,您可能会产生一些堆栈帧开销)。

它还取决于某事实际上做了什么,以及这些函数是如何被调用的(即它是不是一些紧密的循环)。

最好剖析一下。

于 2013-06-21T08:00:26.360 回答