[英]Temporaries in member functions - C++
將一些代碼投入工作后,我正在嘗試對其進行優化。 我要避免的一件事是創建臨時對象。 上一堂課
class foo{
private:
int a;
public:
foo(int sa):a(sa);
~foo(){}
inline int multiply(int b) {return a*b;}//temporary?
};
英特爾編譯器給了我這里使用的臨時創建/引用臨時文件。 是否正在創建任何臨時變量?
編輯:編輯了返回類型。 另外,我認為沒有乘法會創建臨時變量,但是intel編譯器給我一個錯誤。
編輯2:在以下請求之后,這是intel編譯器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));
^
問題是要了解編譯器在做什么,而不是太討厭。
謝謝!
不用擔心
您正在做的事情被稱為“過早的微觀優化”,這是許多邪惡的根源 。
嘗試進行微優化在很大程度上也是徒勞的
無需先對代碼進行性能分析並確定需要優化的位置,就可以進行微優化,這完全是在浪費時間。 您可能最終將一個耗時數百萬皮秒的例程減少了皮秒。 何必呢?
編譯器將大大優化您的代碼。 例如,MicroSoft擁有一群人,他們的唯一工作就是在優化器上工作。 他們是非常聰明的人,每天整天都在努力尋找優化代碼的方法。 在這種情況下,臨時人員通常會被優化掉。 讓他們做自己的事。 他們比你更好。
微觀優化通常以難以理解的代碼為代價。 難以理解的代碼更容易出現缺陷。 如果您的函數返回“ fA @#zzzzzzzzz”而不是“ foo”,則保存的這4皮秒毫無價值。
首先,為您的任務選擇正確的算法。 然后編寫實現這些算法的良好,健壯的代碼。 概要文件處於釋放模式。 在分析器的指導下,找到確實需要優化的位置(如果有的話)。 然后優化。
這並不能真正回答您的問題(我不確定自己在哪里創建臨時變量),但是總的來說,創建臨時原始變量不會節省任何速度,因為唯一的區別是所使用的堆棧空間-因此是否除非有頁面錯誤(這種可能性很小),否則堆棧指針將增加4字節或8字節與程序的速度無關。 因此,您不太可能看到類似這樣的性能提升,特別是如果編譯器通過將變量放入寄存器來優化代碼時。
我認為編譯器會發出警告,因為它會翻譯:
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之間共享。
a*b
創建一個新的臨時文件。 無論問題文本的其余部分到底意味着什么,我都不知道,但是就您使用“臨時”一詞而言,就創建了一個。
給定您聲稱的代碼,編譯器在抱怨...編譯器不應在抱怨。 既然您還沒有包含真正的錯誤...我絕對不知道為什么您認為它在抱怨您所聲稱的抱怨。
編輯:
假設您聲稱編輯中的代碼是導致您最后引用的錯誤的REAL代碼,那么我敢打賭,編譯器已經被抱怨的那一行完全弄糊塗了:
const complex <double> I = (0.0,I);
我不知道您打算這樣做,但是對我來說這並不合法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.