将结构体传递给c++函数(效率)

passing struct to a function c++ (efficiency)

本文关键字:函数 效率 c++ 结构体      更新时间:2023-10-16

我在一个简单的代码上测试计时,我没有看到区别。在第一个块中,它的行为就像只传递了指针,在情况2和3中,它的行为就像通过值而不是通过引用复制整个结构体。编辑:::结构:

struct e{
    vector<int> a;
};

该代码耗时0秒:

void ola(e &a)
{
    a.a[0] = 1;
    a.a[9999] = 1;
}
int main()
{
    e *a;
    a->a.resize(10000000, 0);
    a->a[0] = 2;
    a->a[99999] = 2;
    ola(*a);
    cout << a->a[0] << " . " << a->a[99999] << endl;
    letras.resize('z' - 'a' + 1);
    string entrada;
}

这个需要0.15秒:

void ola(e &a)
{
    a.a[0] = 1;
    a.a[9999] = 1;
}
int main()
{
    e a;
    a.a.resize(10000000, 0);
    a.a[0] = 2;
    a.a[99999] = 2;
    ola(a);
    cout << a.a[0] << " . " << a.a[99999] << endl;
    letras.resize('z' - 'a' + 1);
    string entrada;
}

但是应该没有什么区别。也许是因为在汇编时,它必须复制struct的所有值,所以我尝试了这个:

void ola(e *a)
{
    a->a[0] = 1;
    a->a[9999] = 1;
}
int main()
{
    e a;
    e* b;
    a.a.resize(10000000, 0);
    b = &a;
    a.a[0] = 2;
    a.a[99999] = 2;
    ola(b);
    cout << a.a[0] << " . " << a.a[99999] << endl;
    letras.resize('z' - 'a' + 1);
    string entrada;
}

在最后一个,我只传递一个指针到a,它需要0,15秒。为什么我看到了这种差异?

好主意。分析您的代码并测试您的假设,但要确保代码实际上符合您的期望,并且分析是准确的。

第一点:向量并不总是通过引用传递。编译器将尽其所能通过引用传递、省略传递或使用许多类似的技巧中的任何一种,因为这样做工作量更少,但当不能这样做时,将复制vector。

第二点:计时代码很棘手。太复杂了,不能在这里讲。但天真的假设几乎总是错误的。一次运行是不够的。经常需要多次运行并对这些运行进行统计分析。

我将忽略情况1不工作的事实,因为一个未初始化的指针将它带到了未定义的区域。那只是一个插曲。

案例1:

void ola(e &a)

a是通过引用传递的,实际上和字面上都是这样。除地址外,不复制其他数据。

ola(*a);

a被解引用以满足引用要求,因此我们使用a处的值。事实上,a是一个指针现在是无关紧要的。ola得到一个引用

案例2:

void ola(e &a)

相同的原型。也通过引用传递。除地址外,不复制其他数据。

ola(a);

a是通过引用传递的

案例3:

void ola(e *a)

再次通过引用传递,但这次引用是一个指针。除地址外,不复制其他数据。

ola(b);

b是指向a的指针,ola是指针。不需要工作。a是通过引用传递的

要按值传递,OP必须写:

void ola(e a)

如果编译器觉得需要,可以进行复制。一个足够聪明的编译器会注意到ola绝对没有副作用,副本被修改和丢弃,并编译函数调用。简单的配置文件可以显示出惊人的高效性能,因为什么都没有发生。

在第一个块中,您使用的指针(a)在使用之前未初始化。我怀疑你在文章中忘记了一些代码。

此外,你不清楚你到底想做什么,你想要做什么?

第一个程序可能在做任何有用的事情之前就崩溃了。A指向内存中无效的位置。应该是:

e *a = new e();
a->a.resize(10000000, 0);