各位大神好,刚刚装的XE7想试一下泛类型,在测试时却发现TList<T>和TObjectList<T>的效率差别太大,用TObjectList<T>完成相同工作3000次是600MS,用TList<T>却是几十秒,求大神指点迷津!
下面是代码:
//定义TlogInfo类
type
  TLogInfo = class
  clientIndex: DWORD;
  opCode: WORD;
  packetData: array [0..99000] of AnsiChar;
  JID: DWORD;
  charName: array [0..17] of AnsiChar;
end;
//定义TLogInfoRecord结构
type
  TLogInfoRecord = record
  clientIndex: DWORD;
  opCode: WORD;
  packetData: array [0..99000] of AnsiChar;
  JID: DWORD;
  charName: array [0..17] of AnsiChar;
end;//此方法需要几十秒
procedure TForm1.Button5Click(Sender: TObject);
var
  LogInfo: TLogInfoRecord;
  tmpPAnsiChar: PAnsiChar;
  i, time: Integer;
  myList: Tlist<TLogInfoRecord>;
begin
 //*使用Tlist<T>为记录集的时候 不需要自己去释放内存 用.clear 或者  delete(0) 都可以*/
  time:=GetTickCount();
  myList:=TList<TLogInfoRecord>.Create;
  for i := 0 to 3000 do
    begin
      tmpPAnsiChar:=dumpMemory(dword(@Application),Length(LogInfo.packetData));
      Move(tmpPAnsiChar[0],LogInfo.packetData[0],Length(LogInfo.packetData));
      LogInfo.JID:= i;      //记录LOGINFO
      if myList.Count > 2000 then    //如果大于指定尺寸则先删除第一个
      begin
        myList.Delete(0);
      end;
      myList.Add(LogInfo);
//      Form1.memo1.Lines.Add(IntToStr(i) + '  ' +IntToStr(myList[i].JID));
//      Sleep(10);
    end;
    Form1.memo1.Lines.Add('TList<T> as Record: ' + InttoStr(GetTickCount() - time));
    myList.Clear;
end;
//此方法约600毫秒
procedure TForm1.TObjectListButtonClick(Sender: TObject);
var
  LogInfo: TLogInfo;
  tmpPAnsiChar: PAnsiChar;
  i, time: Integer;
  logInfoList1: TObjectList<TLogInfo>;
begin
  time:= GetTickCount();
  logInfoList1 := TObjectList<TLogInfo>.Create(True);
  for i := 0 to 3000 do
    begin
        LogInfo:=TLogInfo.Create;
        tmpPAnsiChar:=dumpMemory(dword(@Application),Length(LogInfo.packetData));
        Move(tmpPAnsiChar[0],LogInfo.packetData[0],Length(LogInfo.packetData));
  //      Form1.MsgMemo.Lines.Add((PAnsiChar(@LogInfo.packetData)));
        LogInfo.JID:= i;
  //      LogInfo.charName;
         //记录LOGINFO
         if logInfoList1.Count > 2000 then    //如果大于指定尺寸则先删除第一个
         //下面两个方法都可以
         logInfoList1.Delete(0);
         //logInfoList.Remove(logInfoList.First);
         logInfoList1.Add(LogInfo);
//         Form1.memo1.Lines.Add(IntToStr(i) + '  ' +IntToStr(logInfoList[0].JID));
//         Sleep(100);
    end;
  Form1.memo1.Lines.Add('TObjectList<T> as Class: ' + InttoStr(GetTickCount() - time));
end;

解决方案 »

  1.   

    TObjectList你存放的是指针(类对象),但TList存放的结构体实例,主要消耗时间在结构体实例复制上了,也就是这个packetData: array [0..99000] of AnsiChar;复制需要消耗大量时间,所以你TList也要存结构体指针才有可比性。
    myList: Tlist<^TLogInfoRecord>;
      

  2.   

    我奇怪为啥TLIST里不用<TLogInfo>呢?难道上面的例子具有可比性么?就好像西瓜和柚子比,皮也不一样,瓤子也不一样。