2015-09-07 2 views
0

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

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

Это FPC 2.6.

ответ

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 байт.

Удачи.

+0

Не было необходимости в демонстрации. Записи - ** типы значений **, классы - ** ссылочные типы **. Вот почему я всегда, хотя примитивный TList в RTL или FCL должен быть записью, а затем только завернутый как класс с виртуальными методами и всеми медленными вещами. –

+0

@Nestedtype Просто прочитайте вопрос еще раз: «_which является эффективным, меньше памяти: байтовые поля или поле записи? _ (Оба в классе)« Но я абсолютно согласен с вами: более простые типы создают более эффективный код :) – Abelisto

+0

Да, i пропустить _both в классе_. Я думаю, что в другом ответе кто-то не был уверен, что макет памяти будет точно таким же, извините, может быть, это не ваше. –

1

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

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; 

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^