将结构传递到函数而不实例化局部变量的效率 [英] Efficiency of passing a struct to a function without instantiating a local variable
问题描述
我最近得知,我可以通过传递aa结构到C ++中的函数来执行以下操作:
(对于不使用更合适的名称,功能,请随时更正我的名字)
#include< iostream>
typedef struct mystruct {
int data1;
int data2;
} MYSTRUCT;
void myfunction(MYSTRUCT _struct){
std :: cout< _struct.data1<< _struct.data2;
}
int main(){
//这是我最近学到的
myfunction(MYSTRUCT {2,3});
return 0;
}
这让我不知道这是比实例化一个本地 MYSTRUCT
并将它的值传递给函数?或者只是临时变量被删除后,只是一个方便的方法做同样的事情?
例如添加此行 #define KBIG 10000000
,这是:
std :: vector< MYSTRUCT& myvector1;
for(long long i = 0; i< KBIG; i ++){
myvector1.push_back(MYSTRUCT {1,1});
}
始终比这更快:
$ b b
std :: vector< MYSTRUCT>我的
for(long long i = 0; i MYSTRUCT localstruct = {1,1};
myvector2.push_back(localstruct);
}
我试过测试它,但结果是相当不一致,每个12秒。有时第一个会更快,其他时候不。当然,这可能是由于测试时的所有后台进程。
简化和编译到汇编器:
extern void emit(int);
typedef struct mystruct {
int data1;
int data2;
} MYSTRUCT;
__attribute __((noinline))
void myfunction(MYSTRUCT _struct){
emit(_struct.data1);
emit(_struct.data2);
}
int main(){
//这是我最近学到的
myfunction(MYSTRUCT {2,3});
return 0;
}
与-O2产生:
$ b b
myfunction(mystruct):
$发生了什么?
pushq%rbx
movq%rdi,%rbx
call emit(int)
sarq $ 32 ,%rbx
movq%rbx,%rdi
popq%rbx
jmp emit(int)
main:
movabsq $ 12884901890,%rdi
subq $ 8 ,%rsp
call myfunction(mystruct)
xorl%eax,%eax
addq $ 8,%rsp
ret
编译器意识到整个结构适合寄存器,并通过值传递方式。
故事的道德:表达意图。让编译器担心细节。
如果你需要一份副本,你需要一份副本。结束了故事。
I recently learned that I can do the following with passing a a struct to a function in C++:
(My apologies for not using a more appropriate name for this "feature" in the title, feel free to correct me)
#include <iostream> typedef struct mystruct{ int data1; int data2; } MYSTRUCT; void myfunction( MYSTRUCT _struct ){ std::cout << _struct.data1 << _struct.data2; } int main(){ //This is what I recently learned myfunction( MYSTRUCT{2,3} ); return 0; }
This makes me wonder is this less costly than instantiating a local
MYSTRUCT
and passing it by value to the function? Or is it just a convenient way to do the same only that the temporary variable is eliminated right afterwards?For example adding this line
#define KBIG 10000000
, is this:std::vector<MYSTRUCT> myvector1; for (long long i = 0; i < KBIG; i++) { myvector1.push_back(MYSTRUCT{ 1,1 }); }
Consistently faster than this:
std::vector<MYSTRUCT> myvector2; for (long long i = 0; i < KBIG; i++) { MYSTRUCT localstruct = { 1,1 }; myvector2.push_back(localstruct); }
I tried testing it, but the results were pretty inconsistent, hovering around 9-12 seconds for each. Sometimes the first one would be faster, other times not. Of course, this could be due to all the background processes at the time I was testing.
解决方案Simplifying slightly and compiling to assembler:
extern void emit(int); typedef struct mystruct{ int data1; int data2; } MYSTRUCT; __attribute__((noinline)) void myfunction( MYSTRUCT _struct ){ emit(_struct.data1); emit(_struct.data2); } int main(){ //This is what I recently learned myfunction( MYSTRUCT{2,3} ); return 0; }
with -O2 yields:
myfunction(mystruct): pushq %rbx movq %rdi, %rbx call emit(int) sarq $32, %rbx movq %rbx, %rdi popq %rbx jmp emit(int) main: movabsq $12884901890, %rdi subq $8, %rsp call myfunction(mystruct) xorl %eax, %eax addq $8, %rsp ret
What happened?
The compiler realised that the entire structure fits into a register and passed it by value that way.
moral of the story: express intent. Let the compiler worry about details.
If you need a copy, you need a copy. End of story.
这篇关于将结构传递到函数而不实例化局部变量的效率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!