我最近了解到,我可以通过将结构传递给C ++中的函数来执行以下操作:
(我很抱歉没有使用更合适的名称"功能"在标题中,随时纠正我)
#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;
}
这让我觉得这比实例化本地MYSTRUCT
要便宜
并通过值传递给函数?或者只是一个方便的方法来做同样的事情,只是事后才消除临时变量?
例如,添加此行#define KBIG 10000000
是:
std::vector<MYSTRUCT> myvector1;
for (long long i = 0; i < KBIG; i++) {
myvector1.push_back(MYSTRUCT{ 1,1 });
}
始终比这更快:
std::vector<MYSTRUCT> myvector2;
for (long long i = 0; i < KBIG; i++) {
MYSTRUCT localstruct = { 1,1 };
myvector2.push_back(localstruct);
}
我试过测试它,但结果非常不一致,每个都徘徊在9-12秒左右。有时第一个会更快,有时则不会。当然,这可能是由于我在测试时的所有后台进程。
答案 0 :(得分:3)
稍微简化并编译成汇编程序:
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;
}
有-O2收益率:
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
发生了什么事?
编译器意识到整个结构适合寄存器并以这种方式传递给它。
故事的道德:表达意图。让编译器担心细节。如果您需要副本,则需要副本。故事结束。
答案 1 :(得分:1)
如果速度有任何问题,请测量复制与使用const ref(即const MYSTRUCT& _struct
)。进行测量时,请确保进行测量&lt; 1&gt; &lt; 2&gt;,然后&lt; 2&gt; &LT 1为卤素;以补偿缓存效果。
建议:避免使用_
作为参数的第一个字符,因为一些保留字以它开头;另外,不要大写struct。
答案 2 :(得分:0)
如果你想加速你的代码,我建议你通过const引用传递结构,如下所示:
void myfunction (const MYSTRUCT& _struct)
{
std::cout << _struct.data1 << _struct.data2;
}
这比传递值要快得多,因为它不会复制整个结构,而只会传递它的地址。
(好吧,在这种情况下不会有太大的区别,因为你的结构只包含2个整数,但你有> 1000个字节(例如),那么会有一个显着的差异)
此外,我建议您使用std::vector<T>::emplace_back
代替std::vector<T>::push_back
std::vector<MYSTRUCT> myvector1;
for (long long i = 0; i < KBIG; i++)
{
myvector1.emplace_back (1, 1);
}
emplace_back
将其参数转发给mystruct
的构造函数,因此编译器不会创建无用的副本。