将struct传递给函数c ++(效率)

时间:2015-10-04 19:16:13

标签: c++ performance function data-structures struct

我在一个简单的代码上测试时间,但我看不出差异。 在第一个块中,它的作用就像只传递指针一样,在第二种情况和第三种情况下,它的作用类似于按值而不是通过引用复制整个结构。 编辑::: 结构:

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秒。为什么我会看到这种差异?

3 个答案:

答案 0 :(得分:2)

正确的想法。描述您的代码并测试您的假设,但要确保代码实际符合您的期望,并且分析是准确的。

第一点:向量并不总是通过引用传递。编译器将尽其所能通过引用传递,删除或拉出任何一个类似的技巧,因为它的工作量较少,但是当它不能时,矢量将被复制。

第二点: 时序代码很棘手。太难以覆盖这里了。但天真的假设几乎总是错误的。一次运行是不够的。通常需要对许多次运行进行许多运行和统计分析。

我将忽略这样一个事实,即案例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绝对没有副作用,修改并丢弃副本,并编译函数调用。这种天真的形象可能表现出惊人的高效性,因为没有任何事情发生。

答案 1 :(得分:1)

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

此外,它还不清楚你想要做什么以及你想要什么时间?

答案 2 :(得分:0)

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

e *a = new e();
a->a.resize(10000000, 0);
相关问题