首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TList <T>的快速拷贝?

TList <T>的快速拷贝?
EN

Stack Overflow用户
提问于 2012-02-28 17:07:47
回答 2查看 3K关注 0票数 9

有没有一种快速复制通用TList的方法?

代码语言:javascript
复制
Copy.Capacity := List.Count;
for Item in List do
  Copy.Add (Item);

是非常慢的。似乎没有办法使用CopyMemory,因为我无法获得内部数组的内存地址(从信息隐藏的角度来看,这是显而易见的)。我怀念像这样的东西

代码语言:javascript
复制
List.Copy (Copy);

它使用内部表示的知识来提高性能。这是可以做到的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-28 17:20:31

对于通用TList<T>,根本不可能实现您想要的功能。这是因为复制T的内容可能不只是一个简单的内存复制。如果T包含任何托管类型(即字符串、接口等)则必须递增这些被管理对象上的引用计数。

  • 如果您的T确实包含托管类型,那么我怀疑您能比您已有的代码做得更好。
  • 如果您的T不包含任何托管类型,则内存复制是可行的,但由于TList<T>不是TList<T>,因此您需要创建自己的类来封装此列表
票数 9
EN

Stack Overflow用户

发布于 2012-02-28 17:37:36

你总是可以重新解释记忆。

代码语言:javascript
复制
type
  TListHack<T> = class(TEnumerable<T>)
  private
    FItems: array of T;
    FCount: Integer;
  public
    class procedure FastAdd(Source, Dest: TList<T>);
  end;

{ TListHack<T> }

class procedure TListHack<T>.FastAdd(Source, Dest: TList<T>);
var
  SourceHack: TListHack<T>;
  DestHack: TListHack<T>;
  TI: PTypeInfo;
begin
  TI := TypeInfo(T);
  if not (TI.Kind in [tkInteger, tkChar, tkFloat,
    tkSet, tkClass, tkMethod, tkWChar, tkInt64, tkClassRef, tkPointer, tkProcedure]) then
    raise Exception.CreateFmt('Type %s is not supported', [TI.Name]);

  if Source.Count = 0 then
    Exit;
  DestHack := TListHack<T>(Dest);
  SourceHack := TListHack<T>(Source);
  if Dest.Capacity < Dest.Count + Source.Count then
    Dest.Capacity := Dest.Count + Source.Count;

  Move(SourceHack.FItems[0], DestHack.FItems[Dest.Count], Source.Count * SizeOf(T));
  DestHack.FCount := DestHack.FCount + Source.Count;
end;

procedure TForm6.FormCreate(Sender: TObject);
var
  Source, Dest: TList<Integer>;
  Arr: TArray<Integer>;
begin
  Source := TList<Integer>.Create;
  Dest := TList<Integer>.Create;
  try
    Source.Add(1); Source.Add(2); Source.Add(3);
    Dest.Add(10);
    TListHack<Integer>.FastAdd(Source, Dest);
    Assert(Dest.Count = 4);
    ShowMessageFmt('%d, %d, %d, %d', [Dest[0], Dest[1], Dest[2], Dest[3]]);
  finally
    Source.Free; Dest.Free;
  end;

  TListHack<IUnknown>.FastAdd(TList<IUnknown>.Create, TLIst<IUnknown>.Create); // exception
end;

但这是非常危险的

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9479089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档