我应该在哪个源文件中定义一个函数

In which source file should I define a function

最近我注意到在一个有多个源文件(file1.cppfile2.cpp、...)的项目中,它可能会影响函数 A 的执行时间,那将是由另一个函数 B 调用,是否在与该函数 B 相同的源文件中定义。

在我的例子中,当两者在同一个 file1.cpp 中定义时,函数 B 占用了大约 90% 的执行时间,而探查器分析没有 return 函数 A 的执行时间(由B).

但是如果它们在单独的文件中定义,那么执行时间会增加约 150%,函数 A 占用约 65% 的时间,而 B 仅为约 25(总共约 90%)。

为什么执行时间增加了?函数定义位置是否会影响它们的调用方式?想不通了。

此时我应该说,我使用的是优化级别 3,因此在这两种情况下,函数 A 都应该内联到 B 中。

编辑:我正在使用 Linux Ubuntu 14.04,并且我使用 g++ 和以下标志进行编译:-O3 -pg -ggdb -Wall -Wextra -std=c++11.

我把A和B儿子也包括进去可以更好理解。如你所愿,A 被另一个 C 函数从 B 调用,但那个函数似乎不是问题:

答:

size_t A (const Matrix& P, size_t ID) {
  size_t j(0);
  while (P[j][0]!=ID) {
    ++j;
  }
  return j;
}

乙:

Matrix B (const Matrix& P, const Matrix& O, Matrix* pREL, double d, const Vector& f) {`

  size_t length (O.size())      ;
  Matrix oREL ( *pREL ) ;

  for (size_t i(0); i<length; ++i) {
  for (size_t j(0); j<=i; ++j) {
    double fi(f[O[i][0]-1]);
    if (f.size()==1) fi = 0.0;
    if (i!=j)  {
        double gAC, gAD, gBC, gBD, fj(f[O[j][0]-1]);
        if (f.size()==1) fj = 0.0;
        gAC = C(pREL,P,O,i,j,dcol,dcol);
        gAD = C(pREL,P,O,i,j,dcol,scol);
        gBC = C(pREL,P,O,i,j,scol,dcol);
        gBD = C(pREL,P,O,i,j,scol,scol);
        oREL[i][j] = 0.25 * (gAC + gAD + gBC + gBD) 
                          * (1 - d*(fi+fj));                        
    } else if (i==j) oREL[i][i] = 0.5 * ( 1.0+C(pREL,P,O,i,i,dcol,scol) ) 
                                      * (1.0-2.0*d*fi );           
    }
 }

  delete pREL;

  return oREL;
}

C:

coefficient C (Matrix * pREL, const Matrix& P, const Matrix& O, 
                    size_t coord1, size_t coord2, unsigned p1, unsigned p2) {
double g;
size_t i, j  ;
i = A(P,O[coord1][p1]);
j = A(P,O[coord2][p2]);
if (i<=j) g = (*pREL)[j][i];
if (i>j ) g = (*pREL)[i][j];

return g;
}

首先,当您关心性能和基准测试时,您应该在编译器中启用 optimizations

我假设你在 Linux 上使用 GCC 所以你用 g++.

编译

如果您关心性能,您应该使用 g++ -Wall -O2 进行编译。

您可以通过编译 并将 g++ -Wall -O2 -flto

链接来启用 link time optimizations

当然你可以使用 -O3 而不是 -O2

是的。编译器只有在内联点知道函数定义时才能内联函数。如果放在其他编译单元,它可能不知道。在你的情况下,我假设编译器是 "thinking":他正在调用这个函数,但我还不知道它在哪里,所以我进行了一个正常的调用,让链接器稍后再担心它。

因此,应该内联的代码通常放在头文件中。