博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
修正 THashedStringList 在插入和 PutObject 时的速度缺陷
阅读量:6115 次
发布时间:2019-06-21

本文共 4068 字,大约阅读时间需要 13 分钟。

建议用 TFastHashedStringListMini ,更安全(版本安全),不过TFastHashedStringList 更清晰完整.

--------------------------------------------------

unit uFastHashedStringList;

//修正 THashedStringList 在插入和 PutObject 时的速度缺陷
//THashedStringList 主要的问题是重写了   ,而插入和 PutObject 等修改内容的操作都会触发这个事件,
//而这个事件是要表明更新索引的,所以第次都更新索引引起了性能的急剧下降
interface
uses
  IniFiles,SysUtils, Classes;
type
  TFastHashedStringListMini = class(THashedStringList)
  private
    FChangeTag:Boolean;
  protected
    procedure Changed; override;
  public
    //在为屏蔽了 Changed ,所以在需要更新索引时一定要调用这个函数
    //procedure SetChangeTag();
    //更新索引
    procedure UpdateIndex();
  end;
//直接来自 TFastHashedString
type
  TFastHashedStringList = class(TStringList)
  private
    FValueHash: TStringHash;
    FNameHash: TStringHash;
    FValueHashValid: Boolean;
    FNameHashValid: Boolean;
    procedure UpdateValueHash;
    procedure UpdateNameHash;
  protected
    //procedure Changed; override;
  public
    FList: PStringItemList;
    destructor Destroy; override;
    function IndexOf(const S: string): Integer; override;
    function IndexOfName(const Name: string): Integer; override;
    procedure PutObject2(Index: Integer; AObject: TObject);//test
    //在为屏蔽了 Changed ,所以在需要更新索引时一定要调用这个函数
    procedure SetChangeTag();
    //更新索引
    procedure UpdateIndex();
  end;
implementation
{ TFastHashedStringList }
//procedure TFastHashedStringList.Changed;
//begin
//  //inherited;
//  //恢复为 procedure TStringList.Changed; 的内容
//
//  //if (FUpdateCount = 0) and Assigned(FOnChange) then
//  //  FOnChange(Self);
//
//  Self.FValueHashValid := True;
//end;
{ THashedStringList }
//procedure THashedStringList.Changed;
//begin
//  inherited Changed;
//  FValueHashValid := False;
//  FNameHashValid := False;
//end;
destructor TFastHashedStringList.Destroy;
begin
  FValueHash.Free;
  FNameHash.Free;
  inherited Destroy;
end;
function TFastHashedStringList.IndexOf(const S: string): Integer;
begin
  UpdateValueHash;
  if not CaseSensitive then
    Result :=  FValueHash.ValueOf(AnsiUpperCase(S))
  else
    Result :=  FValueHash.ValueOf(S);
end;
function TFastHashedStringList.IndexOfName(const Name: string): Integer;
begin
  UpdateNameHash;
  if not CaseSensitive then
    Result := FNameHash.ValueOf(AnsiUpperCase(Name))
  else
    Result := FNameHash.ValueOf(Name);
end;
//--------------------------------------------------
procedure TFastHashedStringList.PutObject2(Index: Integer; AObject: TObject);
begin
//  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
//  Changing;
  if FList= nil then
  ReallocMem(FList, 20000 * 2000 * SizeOf(TStringItem));
  FList^[Index].FObject := AObject;
  Changed;//是这一个造成特别的慢//clq
end;
//--------------------------------------------------
procedure TFastHashedStringList.SetChangeTag;
begin
  FValueHashValid := False;
  FNameHashValid := False;
end;
procedure TFastHashedStringList.UpdateIndex;
begin
  SetChangeTag();
  UpdateValueHash;
  UpdateNameHash;
 
end;
procedure TFastHashedStringList.UpdateNameHash;
var
  I: Integer;
  P: Integer;
  Key: string;
begin
  if FNameHashValid then Exit;
 
  if FNameHash = nil then
    FNameHash := TStringHash.Create
  else
    FNameHash.Clear;
  for I := 0 to Count - 1 do
  begin
    Key := Get(I);
    P := AnsiPos('=', Key);
    if P <> 0 then
    begin
      if not CaseSensitive then
        Key := AnsiUpperCase(Copy(Key, 1, P - 1))
      else
        Key := Copy(Key, 1, P - 1);
      FNameHash.Add(Key, I);
    end;
  end;
  FNameHashValid := True;
end;
procedure TFastHashedStringList.UpdateValueHash;
var
  I: Integer;
begin
  if FValueHashValid then Exit;
 
  if FValueHash = nil then
    FValueHash := TStringHash.Create
  else
    FValueHash.Clear;
  for I := 0 to Count - 1 do
    if not CaseSensitive then
      FValueHash.Add(AnsiUpperCase(Self[I]), I)
    else
      FValueHash.Add(Self[I], I);
  FValueHashValid := True;
end;
{ TFastHashedStringListTmp }
procedure TFastHashedStringListMini.Changed;
begin
  //inherited;
  //恢复为 procedure TStringList.Changed; 的内容
  //if (FUpdateCount = 0) and Assigned(FOnChange) then
  //  FOnChange(Self);
  //这样修改不太安全,不过比全部重写要好
  if (UpdateCount = 0) and Assigned(OnChange) then
    OnChange(Self);
  //--------------------------------------------------
  if FChangeTag then inherited;
  FChangeTag := False;
end;
procedure TFastHashedStringListMini.UpdateIndex;
begin
  FChangeTag := True;
  Changed;
end;
end.

转载地址:http://mjvka.baihongyu.com/

你可能感兴趣的文章
小程序: 查看正在写的页面
查看>>
dedecms生成文档数据库崩溃 mysql daemon failed to start
查看>>
Linux的50个基本命令
查看>>
Objective-C中创建单例方法的步骤
查看>>
[转]无法安装MVC3,一直卡在vs10-kb2483190
查看>>
Codeforces 520B:Two Buttons(思维,好题)
查看>>
web框架-(二)Django基础
查看>>
Jenkins持续集成环境部署
查看>>
emoji等表情符号存mysql的方法
查看>>
检查磁盘利用率并且定期发送告警邮件
查看>>
MWeb 1.4 新功能介绍二:静态博客功能增强
查看>>
linux文本模式和文本替换功能
查看>>
Windows SFTP 的安装
查看>>
摄像机与绕任意轴旋转
查看>>
rsync 服务器配置过程
查看>>
预处理、const与sizeof相关面试题
查看>>
爬虫豆瓣top250项目-开发文档
查看>>
Elasticsearch增删改查
查看>>
oracle归档日志增长过快处理方法
查看>>
有趣的数学书籍
查看>>