낚이면 안되는 게 THashedStringList 가 아니라는 것.
코드웨이에서 퍼온 것임.
아래는 그 게시물 내용.
사전검색과 같이 대량의 데이터를 빈번히 검색할 때에는 TStringList의 속도가 너무 느려 사용할 수 없죠.
THashedStringList가 Hash를 이용하기 때문에 월씬 속도가 빠르지만 두가지 단점이 있습니다.
먼저 hash크기가 255로 고정되어 있어서 데이터의 양이 많아질 수록 해쉬값 충돌로 인해 검색 속도가
느려진다는 점이고, 두번째는 삽입/삭제가 발생하면서 검색하면 최악의 성능을 보인다는 것입니다.
이는 값이 변경이 발생한 후 검색을 하면 해쉬를 다시 생성하기 때문에 시간이 많이 소요됩니다.
그래서 THashedStringList를 참고로 해서 위의 문제점을 수정한 클래스를 만들어 보았습니다.
약 290000건의 데이터를 가지고 테스트해 본결과
삽입 후 검색 삽입/검색을 동시에
TStringList 측정 포기 측정 포기
THashedStringList 27초 측정 포기
THashStringList 2초 2초
좀 더 빠른 검색을 원하시면 Jedi에 있는 TStringHaspMap를 이용해 보세요.
코드는 그리 길지 않으므로 본문에 바로 첨부함.
unit HashStringList;
interface
uses
Classes, SysUtils, IniFiles;
Classes, SysUtils, IniFiles;
type
THashStringList = class(TStringList)
private
FValueHash: TStringHash;
FHashSize: Integer;
procedure AddHash(const S: string; Index: Integer);
procedure DeleteHash(Index: Integer);
protected
public
constructor Create(HashSize: Integer);
destructor Destroy; override;
function Add(const S: string): Integer; override;
procedure Delete(Index: Integer); override;
function IndexOf(const S: string): Integer; override;
function Contains(const S: string): Boolean;
procedure Remove(const S: string);
end;
THashStringList = class(TStringList)
private
FValueHash: TStringHash;
FHashSize: Integer;
procedure AddHash(const S: string; Index: Integer);
procedure DeleteHash(Index: Integer);
protected
public
constructor Create(HashSize: Integer);
destructor Destroy; override;
function Add(const S: string): Integer; override;
procedure Delete(Index: Integer); override;
function IndexOf(const S: string): Integer; override;
function Contains(const S: string): Boolean;
procedure Remove(const S: string);
end;
implementation
{ THashStringList }
function THashStringList.Add(const S: string): Integer;
begin
Result:= inherited Add(S);
AddHash(S, Result);
end;
begin
Result:= inherited Add(S);
AddHash(S, Result);
end;
procedure THashStringList.AddHash(const S: string; Index: Integer);
begin
FValueHash.Add(S, Index);
end;
begin
FValueHash.Add(S, Index);
end;
function THashStringList.Contains(const S: string): Boolean;
begin
Result:= IndexOf(S) <> -1;
end;
begin
Result:= IndexOf(S) <> -1;
end;
constructor THashStringList.Create(HashSize: Integer);
begin
// 대소문자를 구별한다.
CaseSensitive:= True;
FHashSize:= HashSize;
FValueHash := TStringHash.Create(FHashSize);
end;
begin
// 대소문자를 구별한다.
CaseSensitive:= True;
FHashSize:= HashSize;
FValueHash := TStringHash.Create(FHashSize);
end;
procedure THashStringList.Delete(Index: Integer);
begin
DeleteHash(Index);
inherited Delete(Index);
end;
begin
DeleteHash(Index);
inherited Delete(Index);
end;
procedure THashStringList.DeleteHash(Index: Integer);
begin
Remove(Self[Index]);
end;
begin
Remove(Self[Index]);
end;
destructor THashStringList.Destroy;
begin
FValueHash.Free;
inherited Destroy;
end;
begin
FValueHash.Free;
inherited Destroy;
end;
function THashStringList.IndexOf(const S: string): Integer;
begin
Result := FValueHash.ValueOf(S);
end;
begin
Result := FValueHash.ValueOf(S);
end;
procedure THashStringList.Remove(const S: string);
begin
FValueHash.Remove(S);
end;
begin
FValueHash.Remove(S);
end;
end.
'Delphi' 카테고리의 다른 글
TStringList, THashedStringList 의 IndexOf 속도차이에 대해서 (0) | 2009.04.18 |
---|---|
[Delphi] 도메인 이름으로 IP주소 가져오기 (0) | 2009.04.18 |
예외 (Exception) 모음 (0) | 2009.04.18 |
ReportMemoryLeaksOnShutdown:=True 사용시 Indy의 어쩔 수 없는 메모리 누수 출력안하기 (0) | 2009.04.18 |
[Delphi] TStrings.Objects 사용 (0) | 2009.04.18 |