只想看看是否有更好的方法可以执行以下操作(总有更好的方法来执行所有操作),因为由于加载的数据量确实会延迟应用程序。

我想用存储在csv文件中的数据填充记录数组,我目前对数组具有固定的长度,但是稍后将使其动态化,因此可以添加到csv文件中。

    type
          TStarCoords = Packed record
            szSystem: String[40];
            fCoordX: Single;
            fCoordY: Single;
            fCoordZ: Single;
          end;

    SystemCoords: Array [0 .. 22379] of TStarCoords;

Const
SYSTEMS = 'Data\Systems.csv';


然后,在oncreate事件上填充数组

procedure TForm1.FormCreate(Sender: TObject);
var
  szFile, sRecord: string;
  Row, Index, i: Integer;
  slList: TStringList;
begin

  szFile := ExtractFilePath(ParamStr(0)) + SYSTEMS;

  if FileExists(szFile) then
    try
      slList := TStringList.Create;
      slList.LoadFromFile(szFile);

      for Row := 0 to slList.Count - 1 do
      begin
        sRecord := slList[Row];

        index := Pos(',', sRecord);
        if index > 0 then
        begin
          SystemCoords[Row].szSystem := Copy(sRecord, 1, index - 1);
          Delete(sRecord, 1, index);
        end;

        index := Pos(',', sRecord);
        if index > 0 then
        begin
          SystemCoords[Row].fCoordX := StrToFloat(Copy(sRecord, 1, index - 1));
          Delete(sRecord, 1, index);
        end;

        index := Pos(',', sRecord);
        if index > 0 then
        begin
          SystemCoords[Row].fCoordY := StrToFloat(Copy(sRecord, 1, index - 1));
          Delete(sRecord, 1, index);
        end;

        SystemCoords[Row].fCoordZ := StrToFloat(sRecord);
      end;
    finally
      slList.Free;
    end;

  for i := Low(SystemCoords) to High(SystemCoords) do
  begin
    cbSystem.Items.Add(SystemCoords[i].szSystem);
  end;
end;


如您所见,我正在使用“ Pos”函数解析csv文件,并在最后循环循环数组以将Star名称添加到组合框,这样做是否更经济?

欢迎任何建议

最佳答案

就像其他人说的那样,可能大部分时间都花在填充组合上。

我认为,当处理TStrings的大更新时,BeginUpdate提出的EndUpdate / Jens Borrisholt's answer技术构成一种有效的方法。



作为一个小问题,如果您的应用程序是唯一可读写数据的应用程序,并且机器和人都不关心CSV格式,则可以考虑使用BlockReadBlockWrite存储采用不同文件格式的记录。功能。

type
  TStarCoords = record
    szSystem: string[40];
    fCoordX,
    fCoordY,
    fCoordZ: Single;
  end;


。 。 。

const
  CFILENAME = '<your path to some file .dat>';


读取数据:

procedure TForm1.FormCreate(Sender: TObject);
var
  lstStarCoords: TList<TStarCoords>;
  f: File;
  starCoords: TStarCoords;
begin
  lstStarCoords := TList<TStarCoords>.Create;
  try

    AssignFile(f, CFILENAME);
    Reset(f, SizeOf(TStarCoords));
    try
      while not Eof(f) do begin
        BlockRead(f, starCoords, 1);
        lstStarCoords.Add(starCoords);
      end;
    finally
      CloseFile(f);
    end;

    cbSystem.Items.BeginUpdate;
    for starCoords in lstStarCoords do
      cbSystem.Items.Add(starCoords.szSystem);
    cbSystem.Items.EndUpdate;

  finally
    lstStarCoords.Free;
  end;
end;


写入数据:

procedure TForm1.WriteStarCoords;
var
  lstStarCoords: TList<TStarCoords>;
  f: File;
  starCoords: TStarCoords;
  i: Integer;
begin
  lstStarCoords := TList<TStarCoords>.Create;
  try

    //let's insert 5k new items
    for i:=1 to 5000 do begin
      with starCoords do begin
        szSystem := 'HYEL YE';
        fCoordX := 122;
        fCoordY := 12.375;
        fCoordZ := 45.75;
      end;
      lstStarCoords.Add(starCoords);
    end;

    AssignFile(f, CFILENAME);
    Rewrite(f, SizeOf(TStarCoords));
    try
      for starCoords in lstStarCoords do
        BlockWrite(f, starCoords, 1);
    finally
      CloseFile(f);
    end;

  finally
    lstStarCoords.Free;
  end;
end;




编辑:使用指针将记录信息直接存储在cbSystem组件中的示例。

这种方法有点“危险”,因为它分配必须手动释放的内存,但可以避免使用TDictionaryTStarCoords.szSystem与相应记录配对。

声明一个指向TStarCoords记录的新类型:

type
  PStarCoords = ^TStarCoords;


读取数据:

procedure TForm1.FormCreate(Sender: TObject);
var
  lstStarCoords: TStringList;
  f: File;
  starCoords: PStarCoords;
begin
  ClearCbSystem;

  lstStarCoords := TStringList.Create(False);
  {another minor enhancement:
   since lstStarCoords does not own any TObject which needs to be freed
   the OwnsObjects property of the TStringList can be set to False
   in order to avoid some code to be execute in some method like Clear and Delete}
  try

    lstStarCoords.BeginUpdate;

    AssignFile(f, CFILENAME);
    Reset(f, SizeOf(TStarCoords));
    try
      while not Eof(f) do begin
        New(starCoords);
        BlockRead(f, starCoords^, 1);
        lstStarCoords.AddObject(starCoords^.szSystem, TObject(starCoords));
      end;
    finally
      CloseFile(f);
    end;

    lstStarCoords.EndUpdate;

    cbSystem.Items.Assign(lstStarCoords);
  finally
    lstStarCoords.Free;
  end;
end;


cbSystem.Clear清除列表不会自动处理必须手动释放的基础指针。每次必须清除ClearCbSystem列表时,请使用cbSystem过程:

procedure TForm1.ClearCbSystem;
var
  i: Integer;
begin
  cbSystem.Items.BeginUpdate;
  for i := cbSystem.Items.Count-1 downto 0 do
    Dispose(PStarCoords(cbSystem.Items.Objects[i]));
  cbSystem.Clear;
  cbSystem.Items.EndUpdate;
end;


销毁表单后,对ClearCbSystem过程的调用可确保在应用程序自身释放cbSystem组件之前先处理指针:

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ClearCbSystem;
end;

10-05 22:43