在函数中声明å˜é‡çš„开销在循环中è¿è¡Œï¼Ÿ

时间:2011-12-09 16:45:56

标签: c++ performance variables declaration

å·²ç»é—®è¿‡that问题了。答案是“局部å˜é‡çš„堆栈空间通常在函数范围内分é…â€ã€‚因此,在循环外部/内部声明å˜é‡çš„开销没有差别。

现在,å‡è®¾æˆ‘们在循环内部有一个带有函数的代ç ç‰‡æ®µï¼š

void do_sth(int &i) {int var=i+1;}
int i = 0;
while(i < 100)
{
    do_sth(i);
    i++;
}

第二个片段,其外部声明了å˜é‡ï¼š

int i = 0;
int var;
while(i < 100)
{
    var = i+1;
    i++;
}

我的问题是 - 在实际场景(使用现代编译器)中第一个片段的开销是多少?如果确实存在开销,那么它有多大?它是å¦ä¸Žåœ¨å¾ªçŽ¯çš„æ¯ä¸ªæ­¥éª¤ä¸­å¯¹æ•´æ•°è¿›è¡Œé¢å¤–的加法(è¿ç®—符+)相比较?

8 个答案:

答案 0 :(得分:2)

å¯ç”¨äº†ä¼˜åŒ–的现代编译器很å¯èƒ½å†…è”函数调用,åªè¦å®ƒç¬¦åˆå†…è”需求(没有外部链接等),因此这两个版本将生æˆç›¸åŒçš„代ç ã€‚

如果函数没有内è”,则确实存在开销:函数调用和函数返回,å‚数在堆栈中传递。这ä¸è¿‡æ˜¯ä¸€ä¸ªç®€å•çš„补充。

答案 1 :(得分:1)

找出答案的最佳方法是查看调试器中的å汇编代ç ã€‚ 在这ç§æƒ…况下,第一个代ç å…·æœ‰å¾ªçŽ¯ä¸­å‡½æ•°è°ƒç”¨çš„开销。根æ®ç”¨äºŽå‡½æ•°çš„调用约定,函数调用å¯èƒ½ä¼šå‘生ä¸åŒçš„事情。汇编代ç ä¸­çš„通常情况是将å‚数推é€åˆ°å †æ ˆï¼Œè°ƒç”¨å‡½æ•°ï¼Œç„¶åŽå‡½æ•°åˆ›å»ºå †æ ˆå¸§ï¼Œå¼¹å‡ºå †æ ˆä»¥èŽ·å–å‚数,并在函数返回时弹出堆栈以获å–调用者调用者的堆栈帧。对于功能体éžå¸¸çŸ­çš„代ç ï¼Œå¤´éƒ¨å¯ä»¥æ˜¯å®žé™…功能体的10å€å·¦å³ã€‚ (10æ¡æŒ‡ä»¤ä¸Ž1æ¡æŒ‡ä»¤ï¼‰ã€‚ 如果将函数定义为内è”函数,则所有开销都会消失。

答案 2 :(得分:0)

如果è¦æ±‚在最基本的级别上优化代ç ï¼Œä»»ä½•åˆç†çš„编译器都会为这两个片段生æˆå®Œå…¨ç›¸åŒçš„指令。

答案 3 :(得分:0)

当å‰çš„编译器足够èªæ˜Žï¼Œå¯ä»¥æ£€æŸ¥å˜é‡å’Œå‡½æ•°çš„使用情况,并在编译时和链接时优化代ç ã€‚因此,在优化之åŽï¼Œä¸¤æ®µä»£ç ä¹‹é—´åº”该有微ä¸è¶³é“的差异。此LLVM链接时间优化文档应æ供更好的相关信æ¯ã€‚

答案 4 :(得分:0)

int i = 0;
int var;
while(i < 100)
{
    var = i+1;
    i++;
}

int i = 0;
while(i < 100)
{
    int var = i+1;
    i++;
}

通常会产生完全相åŒçš„代ç ã€‚但是有充分的ç†ç”±ä½¿ç”¨ç¬¬äºŒç§ã€‚
它的æ„图更清晰,代ç å¯ä»¥æ›´å¥½åœ°è¿›è¡Œä¼˜åŒ–,因为编译器知é“var仅在循环的æŒç»­æ—¶é—´å†…需è¦

答案 5 :(得分:0)

我å‡è®¾å…许编译器最好地优化代ç ï¼ˆå¦åˆ™è°ˆè®ºæ€§èƒ½æœ‰ç‚¹æ— æ„义)。

如果在示例中编译循环时do_sth的主体是å¯è§çš„,编译器很å¯èƒ½ä¼šå†…è”它,然åŽåˆ é™¤var的赋值(并为{{1}分é…堆栈空间})作为死代ç ï¼Œå› æ­¤å¯¹äºŽè¿™ç§æƒ…况,开销实际上并ä¸å­˜åœ¨ã€‚如果无法内è”var,则函数调用的æˆæœ¬æ¯”int的声明更令人担忧。如果函数å¯ä»¥å†…è”,å³ä½¿do_sthä¸æ˜¯æ­»ä»£ç ï¼Œç¼–译器也有å¯èƒ½å°†ç¬¬ä¸€ä¸ªç‰ˆæœ¬è½¬æ¢ä¸ºç¬¬äºŒä¸ªç‰ˆæœ¬ã€‚所以对于这样的例å­æ¥è¯´çœŸçš„没关系。

如果你的å˜é‡æ˜¯ä¸€ä¸ªæ›´å¤æ‚的类型(éžPOD classtype),这很é‡è¦ã€‚在这ç§æƒ…况下,第一个版本将为æ¯æ¬¡è¿­ä»£è°ƒç”¨æž„造函数和æžæž„函数一次,而第二个版本将为æ¯æ¬¡è¿­ä»£è°ƒç”¨èµ‹å€¼è¿ç®—符一次,并且åªå¯¹æž„造函数和æžæž„函数调用一次。但请注æ„,这并没有说明哪个版本更快(å–决于这些方法的实现)。

答案 6 :(得分:0)

您确定已正确解决了问题/ç–‘é—®å—?根æ®æ‚¨å‘布的内容 - do_sth函数将具有通常的函数调用开销。如果你内è”它会消除开销。

答案 7 :(得分:0)

我想知é“的是 - 整个程åºæ‰§è¡Œæ—¶é—´å è¿™ä¸ªå¾ªçŽ¯çš„百分比是多少?

例如,如果这åªæ˜¯ä¸€ä¸ªæµ‹è¯•ç¨‹åºï¼Œå¹¶ä¸”您正在执行该代ç 1e9次并对其进行计时,而ä¸æ‰§è¡Œä»»ä½•å…¶ä»–æ“作,则将 在函数调用时产生显ç€å·®å¼‚内è”与å¦ã€‚

æ ¹æ®æˆ‘çš„ç»éªŒï¼Œåœ¨ä»»ä½•çœŸå®žçš„程åºä¸­ï¼Œè¿™ç§å¾ªçŽ¯å¾ˆå°‘å ç”¨å¾ˆå¤šæ—¶é—´ã€‚ 我认为你ä¸éœ€è¦è¢«å‘ŠçŸ¥è¿™ä¸€ç‚¹ï¼Œä½†æ˜¯ä¸€äº›ç¨‹åºå‘˜å¿…须学会一ç§æ¯”例感。 ç†å‘ä¸ä¼šæœ‰åŠ©äºŽå‡è‚¥ã€‚