关于在c中广泛使用realloc()?

时间:2012-03-10 23:23:38

标签: c tree realloc

为了提高计算速度,我需要在树中存储大量数据。一些节点应该包含内部点的平均属性而另一些不应该包含,例如典型的光节点只包含子节点的地址和典型的常规节点,这两个地址加上一些信息。我正在寻找一种智能方法,使用最少的内存将这两种节点存储在同一个树中。

我正在使用c。我首先使用结构(node.properties,node.Left,nodeRight等)构建我的树,但它需要太多内存(如果你熟悉结构,你可能会弄清楚原因),所以我有回到我的树的某种“内联”组织,在前两个插槽中存储子节点的地址,并且(最终)在以下插槽中存储其余信息。

所以我虽然有两种方法可以做到这一点。一种方法是预测节点总数(简单)并分配足够的内存以将所有节点存储为常规节点(子节点地址有2个插槽,信息有1个插槽)。另一种方法是在我们沿树下去时重新分配树数组。

第一个问题:在效率方面广泛使用realloc()真的是一件好事吗?

第二个问题:这样做是否有更聪明的方法(在记忆方面)?

2 个答案:

答案 0 :(得分:0)

好吧,我认为我找到了妥协方案。首先确定树的大小,并且分配大小为2的指针数组X节点的数量。每个节点将有(1)[指向]一个整数数组,其中包含左子节点的索引,右子节点的索引和点数,以及(2)[指向]包含双精度数组的数组所有有用的信息。当例程构建树时,将根据节点的类型计算为“double”数组分配的空间。

到目前为止,这是我能想到的“最便宜”的解决方案。但是如果你能说服我转换(long)index_in_double很快,那么在数组中只能使用double。

答案 1 :(得分:0)

为了说明使用索引而不是指针的要点,请参阅使用(短)int索引的this hash table implementation,节省一些宝贵的位。 tiny_find()函数编译到这个程序集(GCC -O2):

        .globl  tiny_find
        .type   tiny_find, @function
tiny_find:
.LFB57:
        .cfi_startproc
        imull   $98765, %edi, %ecx
        movl    $274877907, %edx
        movl    %ecx, %eax
        mull    %edx
        movl    $-1, %eax
        shrl    $6, %edx
        imull   $1000, %edx, %edx
        subl    %edx, %ecx
        movzwl  %cx, %ecx
        movzwl  table+4(,%rcx,8), %edx
        cmpw    $-1, %dx
        je      .L12
        movzwl  %dx, %eax
        testb   $1, table+7(,%rax,8)
        jne     .L19
        jmp     .L13
        .p2align 4,,10
        .p2align 3
.L21:
        movzwl  table+4(,%rax,8), %eax
        cmpw    $-1, %ax
        je      .L20
        movzwl  %ax, %eax
        testb   $1, table+7(,%rax,8)
        je      .L13
.L19:
        cmpl    table(,%rax,8), %edi
        jne     .L21
.L13:
        movzbl  table+6(,%rax,8), %eax
.L12:
        rep
        ret
        .p2align 4,,10
        .p2align 3
.L20:
        movl    $-1, %eax
        ret
        .cfi_endproc
.LFE57:
        .size   tiny_find, .-tiny_find

内循环(走链表)是L21和L13之间的部分。我不会说代码效率低下。