【问题标题】:C : cost of copying data from heap to stack?C:将数据从堆复制到堆栈的成本?
【发布时间】:2013-10-25 02:00:01
【问题描述】:

我正在学习 C 并想询问最佳实践。

这里有两个实现(衬衫是结构):

实施1:

void printShirt(shirt shirt){
    printf("(%d , %s)",shirt.size,shirt.color);
}
void printShirts(shirt * shirts, int nbShirts){
    int i;
    for(i=0;i<nbShirts;i++) printShirt(shirts[i]);
    printf("\n");
}

实施 2:

void printShirt(shirt * shirt){
    printf("(%d , %s)",shirt->size,shirt->color);
}
void printShirts(shirt * shirts, int nbShirts){
    int i;
    for(i=0;i<nbShirts;i++) printShirt(&shirts[i]);
    printf("\n");
}

如果我是正确的 (?),在实现 1 中,每件衬衫的数据在打印之前从堆复制到堆栈。但这在实现 2 中不会发生(?)。

对于大型数组和结构,这可能会产生影响吗? 是否有一些最佳实践可以遵循?

【问题讨论】:

    标签: c memory-management heap-memory stack-memory


    【解决方案1】:

    是的,这可能会对大型结构或较小结构的大型数组产生影响,除非编译器能够优化调用。当您已经拥有数据副本时避免复制数据更为正常 - 特别是如果您不打算修改副本。

    复制一个结构是相当快的——它本质上只是将字节从内存中的一个位置传送到另一个位置......但是复制一个指针更快。如果结构很小,您可以考虑复制它以避免额外的指针取消引用。但是,现在您很可能会过早地进行优化。

    回到指针方法,通常你通过接收const指针来帮助程序员意识到数据不会被修改:

    void printShirt( struct shirt const * shirt )
    

    您的示例有点幼稚,因为printf 的成本远高于复制甚至相对较大的结构。但我明白你想问什么。

    【讨论】:

    • 所以要权衡取舍吗?数据复制与取消引用?
    • 是的,但您的代码中几乎总是存在比那个更大的瓶颈。它是特定于平台的(eg 64 位指针与 32 位指针)。因此我提到了过早的优化。 99.99% 的情况下,您会希望通过指针传递结构。
    • 只是为了确保我真的明白了,在任何代码中 "d[i]=5" 和 "&d[i]->5" 做完全相同的事情(不是从结果的角度来看,从内存管理的角度来看)? (这里我的意思不是优化我的代码,只是为了确保我得到了正确的主要原则)。
    • 将指针作为&amp;shirts[i]shirts+i 传递是正确的。我不明白你所说的&amp;d[i]-&gt;5 是什么意思——那是语法错误。你的意思是d[i].color vs (&amp;d[i])-&gt;color?那么是的,他们访问相同的内存。除非编译器可以将其优化掉(就像在这个简单的示例中一样),否则引用运算符 &amp; 和结构取消引用运算符 -&gt; 将占用额外的 cpu 周期,因此它们完全相同相同.
    【解决方案2】:

    您将在实现 2 中使用更少的内存,因为您只需将地址(指针)传递给 printShirt 函数。如果 sizeof shirt 很大,实现 1 可能会很慢,而且它也会消耗更多内存,因为您要复制结构中的所有字段。

    【讨论】:

      猜你喜欢
      • 2012-09-20
      • 2018-08-25
      • 2011-11-26
      • 2021-10-20
      • 2022-10-17
      • 2015-07-04
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多