成员函数中的临时函数 - C ++

时间:2010-12-23 20:23:36

标签: c++

在使用一些代码后,我正在尝试优化它。我试图避免的一件事是创造临时工。给定一个班级

class foo{
   private:
     int a;
   public:
     foo(int sa):a(sa);
     ~foo(){}
    inline int multiply(int b) {return a*b;}//temporary?
};

intel编译器给我这里使用的临时创建/引用临时。是否正在创建临时变量?

编辑:编辑了返回类型。此外,我认为没有在multiply中创建临时变量,但是intel编译器给我一个错误。

编辑2:在下面的请求之后,这是一个完整的代码,英特尔编译器v.12给出了错误:

 #include <iostream>
 #include <complex>

 using namespace std;
 const double pi = 3.1415;
 const complex <double> I = (0.0,I);
 const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));

  class foo{
     private:
       complex <double> a;
     public:
       foo(complex <double> sa):a(sa){}
       ~foo(){}
       inline complex <double> multiply(complex<double> b) 
       {return  a*sqrt(b);}
   };

编译行是

  icc -g -O2 -w2 -debug parallel -Wcheck -Weffc++ -mp -fp-stack-check -wd981 -wd2015 -wd1418  test.cpp -o  test

结果警告是

  test.cpp(7): remark #383: value copied to temporary, reference to temporary used
  const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));
                                         ^

问题是理解编译器正在讨论什么,而不是hanous。

谢谢!

4 个答案:

答案 0 :(得分:4)

不要担心。

您正在做的事情称为“过早的微优化”,它是root of much evil

尝试微观优化也很无济于事

  1. 微观优化,无需首先分析代码并确定需要优化的地方,这完全是浪费时间。您可能最终会从需要数百万皮秒的例程中刮掉皮秒。为什么要这么麻烦?

  2. 编译器会比您更好地优化代码。例如,MicroSoft拥有一组人员,他们唯一的工作就是使用优化器。他们是非常聪明的人,每天都在工作,寻找优化代码的方法。在这种情况下,临时工具通常会被优化掉。让他们做他们的事。他们比你更擅长。

  3. 微优化往往以更难理解代码为代价。难以理解的代码更容易出现缺陷。如果您的函数返回“fA @#zzzzzzz”而不是“foo”,那么您保存的那4皮秒就毫无价值。

  4. 首先,为您的任务选择正确的算法。然后编写实现这些算法的优秀,健壮的代码。发布模式第二个配置文件在分析器的指导下,找到真正需要优化的地方,如果有的话。然后优化。

答案 1 :(得分:1)

这并没有真正回答你的问题(我不确定自己创建临时变量的位置),但一般来说,创建临时原始变量不会保存任何速度,因为只有差异是使用的堆栈空间 - 因此堆栈指针是否增加4个字节或8个字节与程序的速度无关,除非出现页面错误(这是非常不可能的)。因此,您不太可能看到任何类似的性能优势,特别是如果编译器通过将变量放入寄存器来优化代码。

答案 2 :(得分:1)

我认为编译器会发出警告,因为它会翻译:

const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));

调用默认的复制构造函数:

Object::complex<double>(const complex<double>&)

将临时对象的引用作为参数,并在对象中生成浅拷贝(如果使用指针则导致数据共享)。基本上这种数据共享+临时寿命是问题的核心。看看下面的“学术”课程。

#include<iostream>

class A
{

public:

  A()
    :attribute(new char[10]) {}

  ~A()
  {
    std::cout << "d'ctor" << std::endl; 
    if(attribute){
      delete [] attribute;
      attribute = 0;
    }
  }

  A& operator +(const char& n)
  {
    //do some operation
    return *this;
  }

  void reset_attribute(char *new_ptr)
  {
    attribute = new_ptr;
  }

private:

  char *attribute;
};

int main()
{
  {//new scope to invoke destructors
    A b;
    A c = b;
    b.reset_attribute(new char[10]);
  }//no problem in this scope

  A a = (A()+2);//problem with a temporary object

  return 0;
}

cygwin 输出:

$ ./a.exe
d'ctor //this is from b or c
d'ctor //this is from b or c
d'ctor //this is from temporary
d'ctor //this is from a
Aborted (core dumped)

delete操作已在同一指针上执行了两次,因为它是在临时对象和 a 之间共享的。

答案 3 :(得分:0)

a*b创建一个新临时用户。无论你的问题文本的其余部分是什么意思,我都不知道,但就你使用“临时”这个词而言,就会创造一个。

鉴于您声称编译器抱怨的代码......编译器不应该抱怨。既然你没有包含真正的错误......我完全不知道为什么你认为它抱怨你声称抱怨什么。

编辑:

鉴于您声称编辑中的代码是导致您最终引用的错误的真实代码,我的赌注是编译器在它抱怨之前完全被该行混淆:

const complex <double> I = (0.0,I);

我不知道你要做什么,但这看起来不合法。