Что эффективно - запись в класс или n полей

У меня есть класс с 8-байтовыми полями. Я могу поместить их в запись и поставить запись в 1 поле класса (запись упакована и работоспособна).

У меня есть 100000 объектов этого класса. Итак, нужен эффективный вариант - что эффективно, меньше памяти: байтовые поля или поле записи?

Это ФПК 2.6.


person Prog1020    schedule 07.09.2015    source источник


Ответы (2)


Пока ни у кого из гуру FPC нет времени отвечать, давайте рассмотрим этот вопрос. Вот код для этого:

program Project1;

type
    TByteArray = packed array[Low(Word)..High(Word)] of Byte;
    PByteArray = ^TByteArray;

    TMyRec = packed record
        f1, f2, f3, f4, f5, f6, f7, f8: Byte;
    end;

    { TMyClass1 }

    TMyClass1 = class
        mark1: Byte;
        f1, f2, f3, f4, f5, f6, f7, f8: Byte;
        mark2: Byte;
        r: TMyRec;
        mark3: Byte;
        constructor Create;
        procedure ShowMe; // Dump of the object's data
    end;

{ TMyClass1 }

constructor TMyClass1.Create;
begin
    mark1 := 66;
    mark2 := 77;
    mark3 := 88;
end;

procedure TMyClass1.ShowMe;
var
    data: PByteArray;
    i: Word;
begin
    data := Pointer(Self);
    for i := 0 to 15 + 4 + 3 do // 4 - some unknown data at the beginning of the class, 3 - marks
        Writeln(data^[i]);
end;

var
    test: TMyClass1;
begin
    test := TMyClass1.Create;
    try
        test.ShowMe;
        Readln;
    finally
        test.Free;
    end;
end. 

И вывод:

0
192
64
0
66 <- Data starts, simple fields
0
0
0
0
0
0
0
0
77 <- Second data portion, record
0
0
0
0
0
0
0
0
88 <- Data ends

Как видим, в обоих случаях 8 полей занимают 8 байт.

Удачи.

person Abelisto    schedule 07.09.2015
comment
Демонстрация была не нужна. Записи — это типы значений, классы — это ссылочные типы. Вот почему я всегда считал, что примитивный TList в RTL или FCL должен быть записью, а затем только обернутым как класс с виртуальными методами и всеми медленными вещами. - person Abstract type; 10.09.2015
comment
@Nestedtype Просто прочитайте вопрос еще раз: что эффективнее, меньше памяти: байтовые поля или поле записи? (оба в классе) Но я полностью с вами согласен: более простые типы производят более эффективный код :) - person Abelisto; 10.09.2015
comment
Да, я скучаю по обоим в классе. Я думаю, что в другом ответе кто-то не был так уверен, что расположение памяти будет точно таким же, извините, может быть, это было не ваше. - person Abstract type; 10.09.2015

Или, если вы считаете, что упаковка действительно важна, просто объявите класс упакованным:

TMyClass1 = packed class
    mark1: Byte;
    f1, f2, f3, f4, f5, f6, f7, f8: Byte;
    mark2: Byte;
    r: TMyRec;
    mark3: Byte;
    constructor Create;
    procedure ShowMe; // Dump of the object's data
end;

Классы всегда будут иметь некоторые накладные расходы, но это не обязательно упаковка полей, а скрытое администрирование. И со временем эти накладные расходы стали больше.

Но 100 000 записей — это мелочь. Если вы потеряете несколько байтов, это составит около 10 МБ или около того, часть памяти самого дешевого ПК, доступного в настоящее время.

person Marco van de Voort    schedule 08.09.2015