以前,给 任远兄 做了一个优化,现在贴出来。
词库大小 10 万条 分析的文本 144 KB
TStringList 单词数 5009 耗时 1241毫秒
TStringList 单词数 5009 耗时 1282毫秒
TStringList 单词数 5009 耗时 1202毫秒
TStringList 单词数 5009 耗时 1222毫秒
TStringList 单词数 5009 耗时 1192毫秒
TStringList 单词数 5009 耗时 1192毫秒
TmyStringList 单词数 5009 耗时 211毫秒
TmyStringList 单词数 5009 耗时 240毫秒
TmyStringList 单词数 5009 耗时 240毫秒
TmyStringList 单词数 5009 耗时 110毫秒
TmyStringList 单词数 5009 耗时 130毫秒
TmyStringList 单词数 5009 耗时 251毫秒
TmyStringList 单词数 5009 耗时 250毫秒
大约快 5倍 左右。
测试代码:
_Source2 := TmyStringList.Create;
_Source2.LoadFromFile(ExtractFilePath(Application.ExeName) + 'c.txt');
TmyStringList(_Source2).CaseSensitive := true;
TmyStringList(_Source2).Sorted := true;
{
_Source2 := TStringList.Create;
_Source2.LoadFromFile(ExtractFilePath(Application.ExeName) + 'c.txt');
TStringList(_Source2).CaseSensitive := true;
TStringList(_Source2).Sorted := true;
}
procedure TForm1.Button2Click(Sender: TObject);
var
c, i: integer;
s: string;
wordstr: string;
KeyFound: integer;
btime: Cardinal;
sl: TStringList;
begin
Label1.Caption := '';
s := Memo1.Text;
//////////////////////
sl := TStringList.Create;
btime := GetTickCount;
c := 0;
for i := 1 to length(s) - 3 do
begin
wordstr := copy(s, i, 4);
KeyFound := _Source2.IndexOf(wordstr);
if KeyFound >= 0 then
begin
sl.add(_Source2[KeyFound]);
inc(c);
end;
end;
Memo3.Lines.add(format('%s 单词数 %d 耗时 %d毫秒', [_Source2.ClassName, c, GetTickCount - btime]));
//////////////////////////
Memo2.Lines.Assign(sl);
FreeAndNil(sl);
end;
优化代码:
FTable: array[0..1024 * 16] of TidxRec; /////////////
procedure TmyStringList.SetSorted(Value: Boolean);
begin
if FSorted <> Value then
begin
if Value then Sort;
FSorted := Value;
if FSorted then
maketable;
end;
end;
function TmyStringList.Find(const S: string; var Index: Integer): Boolean;
var
L, H, I, C: Integer;
idx: Integer;
begin
Result := False;
{
L := 0;
H := FCount - 1;
}
idx := getstridx(@(s[1]), length(s));
with FTable[idx] do
begin
if beginIdx < 0 then
exit;
L := beginIdx;
H := endIdx;
end;
。。。。。。。。。
procedure TmyStringList.maketable;
var
l, i, idx: integer;
begin
for i := 0 to high(FTable) do
with FTable do
begin
beginIdx := -1;
endIdx := -1;
end;
for i := 0 to FCount - 1 do
begin
with FList do
begin
l := length(FString);
idx := getstridx(@(FString[1]), l);
end;
with FTable[idx] do
begin
if beginIdx < 0 then
begin
beginIdx := i;
endIdx := i;
end
else
endIdx := i;
end;
end;
end;