有許多程序員都喜歡使用TStringList類作為鍵值存儲,這是不錯的用法。但是TStringList本身只是對數據線性的存儲,當數據量大時,對其檢索效率極為低下。Delphi在在IniFiles 單元中定義了另一個TStringList類,采用了哈希技術存儲數據,它就是THashedStringList類。下面這段代碼就是摘自IniFiles單元中對THashedStringList的定義。
THashedStringList = class(TStringList)
private
FValueHash: TStringHash;
FNameHash: TStringHash;
FValueHashValid: Boolean;
FNameHashValid: Boolean;
procedure UpdateValueHash;
procedure UpdateNameHash;
protected
procedure Changed; override;
public
destructor Destroy; override;
function IndexOf(const S: string): Integer; override;
function IndexOfName(const Name: string): Integer; override;
end;
基本的TStringList類是使用數組以線性方式保存所有子項的,所以無論使用其IndexOf方法還是IndexOfName方法都是使用線性查找法,這種查尋方法的時間復雜度在最好情況為T(1),即第一個子項即為查詢項,最壞情況為T(N),N為子項個數,即查找項為最後一項。所以,當數據量比較大時其查詢是毫無效率可言的。
THashedStringList類中添加了兩個TStringHash私有成員,分別用來存放對其子項鍵名哈希表和鍵值哈希表。當調用其IndexOf方法或是IndexOfName方法時,此類會首先檢查是否已經為鍵值或是鍵名創建哈希表,如果沒有,則創建之,否則直接使用哈希算法時行查找。
function THashedStringList.IndexOf(const S: string): Integer;
begin
UpdateValueHash; //創建鍵值哈希表
if not CaseSensitive then
Result := FValueHash.ValueOf(AnsiUpperCase(S))
else
Result := FValueHash.ValueOf(S);
end;
function THashedStringList.IndexOfName(const Name: string): Integer;
begin
UpdateNameHash; //創建健名哈希表
if not CaseSensitive then
Result := FNameHash.ValueOf(AnsiUpperCase(Name))
else
Result := FNameHash.ValueOf(Name);
end;
學過數據結構的朋友都知道,當數據量不是很大時,如幾百、幾千時哈希算法的優勢並不是很明顯,和普通的線性查找性能差不了多少,但是隨著數據量在增大,其性能的提升是相當可觀的。所以建議各位程序員朋友,如果需要使用TStringList存儲大數據量時,請使用THashedStringList代替。