只是想知道是否有更好的方法来执行以下操作(总有一种更好的方法可以解决所有问题),因为在加载时会因应用数据而延迟应用程序。
我想用我存储在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文件的函数,并在最后循环数组以将星名添加到组合框中,是否有更经济的方法呢?
欢迎任何建议
答案 0 :(得分:4)
它看起来效率不高。
Delete
。 你的下一步是解决瓶颈问题。我们只能猜测,因为我们缺少这么多信息。我们不知道数据是静态的,有多大,等等。
答案 1 :(得分:2)
您可以使用<li><a href="<?php echo base_url();?>index.php/login">Login</a></li>
<li><a href="<?php echo base_url();?>index.php/aboutus" >About Us</a></li>
来解析该行。在下面我假设你有用逗号分隔的元素。
由于你将你的记录的字符串表示放入一个组合框我告诉你,你以后在你的程序中需要另一种方法:从字符串中找到一个TStarCoords。鉴于我在重新考虑你将你的元素放在TStringlist
instread和数组中。
TDictionary
答案 2 :(得分:2)
像其他人所说,可能大部分时间花在填充组合上。
在我看来,当处理TStrings
BeginUpdate
提出的EndUpdate
/ Jens Borrisholt's answer技术的重大更新时,BlockRead
构成了一种有效的方法。
作为一个小问题,如果您的应用程序是唯一一个写入和读取数据的应用程序,并且机器和人类都不关心CSV格式,您可以考虑使用{{3}来存储采用不同文件格式的记录。 }和BlockWrite
函数。
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
组件中的示例。
这种做法多一点危险&#34;因为它分配了必须手动释放的内存,但允许避免使用TDictionary
将TStarCoords.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;