我有一个简单的数组:
Myarray<T> = array[0..100] of T;
如何尽快将其复制到另一个数组中。 请注意,源始终是普通的通用数组,目标可以是动态数组。 (但我怀疑这很重要)。
我试过了
move(Source[0], dest[0], count * sizeof(T));
但这对于托管类型来说效果不佳。
我希望得到比以下更快的东西:
for i:= 0 to count -1 do D[i]:= S[i];
我有什么选择?
背景
该数组是 BTree 结构的一部分,并且正在进行大量复制。
我需要速度。
最佳答案
我在 Google+ 上问了同样的问题 - https://plus.google.com/u/0/116430453567926016001/posts/b1u1shzkmrW
该代码由 Stefan Glienke 编写,我已在此处重新发布了代码,并对两个变量类型进行了细微更改,因此它是 64 位兼容的。
uses
TypInfo,
SysUtils;
type
TArray = record
class function Clone<T>(const source: T): T; static;
end;
function DynArrayLength(const A: Pointer): NativeInt;
type
PDynArrayRec = ^TDynArrayRec;
TDynArrayRec = packed record
{$IFDEF CPUX64}
_Padding: LongInt;
{$ENDIF}
RefCnt: LongInt;
Length: NativeInt;
end;
begin
Result := 0;
if A <> nil then
Result := PDynArrayRec(PByte(A) - SizeOf(TDynArrayRec))^.Length;
end;
{$POINTERMATH ON}
type
PArray = ^Pointer;
{$POINTERMATH OFF}
procedure CopyArrayDeep(Dest, Source: PArray; TypeInfo: Pointer; Count: NativeInt);
var
typeData: PTypeData;
elType: PPTypeInfo;
i: Integer;
len : NativeInt;
begin
if (Source = nil) or (Count = 0) then
Exit;
typeData := GetTypeData(TypeInfo);
elType := typeData.elType;
if (elType <> nil) and (elType^.kind = tkDynArray) then
begin
for i := 0 to Count-1 do
begin
len := DynArrayLength(Source[i]);
DynArraySetLength(Dest[i], elType^, 1,@len);
CopyArrayDeep(Dest[i], Source[i], elType^, len);
end;
end
else
if elType <> nil then
CopyArray(Dest, Source, elType^, Count)
else
Move(Source^, Dest^, Count * typeData.elSize);
end;
class function TArray.Clone<T>(const source: T): T;
var
p: PTypeInfo;
count: NativeInt;
i: Integer;
begin
p := TypeInfo(T);
if p.Kind <> tkDynArray then
raise ENotSupportedException.Create('type not supported');
count := DynArrayLength(PArray(@source)^);
DynArraySetLength(PArray(@Result)^, p, 1,@count);
CopyArrayDeep(PArray(@Result)^, PArray(@source)^, p, count);
end;
关于arrays - 如何加快通用数组的复制速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25612322/