什么是高效-在class或n个字段中记录
What is efficient- record in class or n fields
我 class 有 8 个字节的字段。我可以将它们放入记录中并将记录放入 1 class 字段中(记录打包且高效)。
我有这个 class 的 100000 个对象。所以需要高效的变体——哪个更高效,内存更少:字节字段还是记录字段?
是FPC 2.6.
趁着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 个字节。
祝你好运。
或者,如果您认为打包真的很重要,只需声明 class 打包:
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 条记录是花生。如果你浪费几个字节,那就是 10MB 左右,是当今最便宜的 PC 内存的一小部分。
我 class 有 8 个字节的字段。我可以将它们放入记录中并将记录放入 1 class 字段中(记录打包且高效)。
我有这个 class 的 100000 个对象。所以需要高效的变体——哪个更高效,内存更少:字节字段还是记录字段?
是FPC 2.6.
趁着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 个字节。
祝你好运。
或者,如果您认为打包真的很重要,只需声明 class 打包:
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 条记录是花生。如果你浪费几个字节,那就是 10MB 左右,是当今最便宜的 PC 内存的一小部分。