Сколько накладных расходов вносят вызовы realloc?

В первой памяти в качестве примера для Панели объект будет выделен автоматически при построении объекта Foo. Во втором случае необходимо выделить память сами. Таким образом, необходимо звонить:

Foo *foo = new Foo();
foo->b = new Bar();

Это может быть желательно, если объект Панели является большим, и Вы не хотите связывать его объектом Foo. Также желательно, когда конструкция объекта Панели независима от создания объекта Foo. В этом случае объект b "введен" в нечто:

Foo *foo = new Foo();
foo->b = b_ptr;

, где b_ptr создается где-то в другом месте и указатель передается нечто.

Для меньших объектов это опасно, поскольку можно забыть выделять память.

8
задан Dariusz 29 May 2013 в 17:23
поделиться

1 ответ

Я думал, что добавлю некоторые эмпирические данные к этому обсуждению.

А простая тестовая программа:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    void *buf = NULL, *new;
    size_t len;
    int n = 0, cpy = 0;

    for (len = 64; len < 0x100000; len += 64, n++) {
        new = realloc(buf, len);
        if (!new) {
            fprintf(stderr, "out of memory\n");
            return 1;
        }

        if (new != buf) {
            cpy++;
            printf("new buffer at %#zx\n", len);
        }

        buf = new;
    }

    free(buf);
    printf("%d memcpys in %d iterations\n", cpy, n);
    return 0;
}

GLIBC на x86_64 приводит к этому выводу:

new buffer at 0x40
new buffer at 0x80
new buffer at 0x20940
new buffer at 0x21000
new buffer at 0x22000
new buffer at 0x23000
new buffer at 0x24000
new buffer at 0x25000
new buffer at 0x26000
new buffer at 0x4d000
new buffer at 0x9b000
11 memcpys in 16383 iterations

musl на x86_64:

new buffer at 0x40
new buffer at 0xfc0
new buffer at 0x1000
new buffer at 0x2000
new buffer at 0x3000
new buffer at 0x4000
new buffer at 0xa000
new buffer at 0xb000
new buffer at 0xc000
new buffer at 0x21000
new buffer at 0x22000
new buffer at 0x23000
new buffer at 0x66000
new buffer at 0x67000
new buffer at 0xcf000
15 memcpys in 16383 iterations

, Таким образом, это похоже, можно обычно полагаться на libc для обработки, изменяет размеры, которые не пересекают границы страницы, не имея необходимость копировать буфер.

способ, которым я вижу его, если Вы не можете найти способ использовать структуру данных, которая избегает копий в целом, пропустите подход track-capacity-and-do-power-of-2-resizes в своем приложении и позвольте Вашему libc сделать тяжелый подъем для Вас.

0
ответ дан 5 December 2019 в 05:24
поделиться