TStringList 与 泛型字典TDictionary 的 哈希功能效率PK

结论:

做HashMap 映射 功能的时候 ,字典TDictionary 功能更强大,且效率更高,比如不仅仅可以存String,还可以存结构和类。

TDictionary类是一个name,value容器,内部是哈希索引,所以对于数据查找非常高效.

unit Unit5;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections, UListMap;

type
  TForm5 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  /// <summary>
  ///  第一种方法:
  ///  班级类,班级里有多个人,这里类里内置好每个人的英文名字和中文名字的映射
  ///  通过英文名字可以找到中文,通过中文名字也可以找到英文
  /// </summary>
  TBanJi111 = class
    const
      /// <summary>
      /// 这叫类常量,可以把人名 英文---->中文 定义在这里
      /// </summary>
      studentNameEnToCnListStr = 'XiaoLi=李飞刀,XiaoWang=王中王,XiaoZhang=张飞';
    public
      /// <summary>
      ///  通过英文获取中文的方法
      /// </summary>
      function getNameCnByEn(const nameEn: string): string;

      /// <summary>
      /// 通过中文获取应该的方法
      /// </summary>
      function getNameEnByCn(const nameCn: string): string;
  end;

  /// <summary>
  ///  第二种方法:
  ///  用2个TStringList属性,
  ///  key,value做下置换
  /// </summary>
  TBanJi222 = class
  private
    FNameEnToCnList: TStringList;
    FNameCnToEnList: TStringList;
    procedure SetNameCnToEnList(const Value: TStringList);
    procedure SetNameEnToCnList(const Value: TStringList);
  public
    constructor Create;
    destructor Destroy; override;
    property NameCnToEnList: TStringList read FNameCnToEnList write SetNameCnToEnList;
    property NameEnToCnList: TStringList read FNameEnToCnList write SetNameEnToCnList;
  end;


  /// <summary>
  /// 第三种方法
  /// 用泛型
  /// </summary>
  TBanJi333 = class
  private
    FNameEnToCnMap: TDictionary<string, string>;
    FNameCnToEnMap: TDictionary<string, string>;
    procedure SetNameCnToEnMap(const Value: TDictionary<string, string>);
    procedure SetNameEnToCnMap(const Value: TDictionary<string, string>);
  public
    constructor Create;
    destructor Destroy; override;
    property NameCnToEnMap: TDictionary<string, string> read FNameCnToEnMap write SetNameCnToEnMap;
    property NameEnToCnMap: TDictionary<string, string> read FNameEnToCnMap write SetNameEnToCnMap;
  end;


  /// <summary>
  ///  第四种方法
  ///  用我自己封装的有序的泛型字典
  /// </summary>
  TBanJi444 = class
  private
    FNameEnToCnMap: TListMap<string, string>;
    FNameCnToEnMap: TListMap<string, string>;
    procedure SetNameCnToEnMap(const Value: TListMap<string, string>);
    procedure SetNameEnToCnMap(const Value: TListMap<string, string>);
  public
    constructor Create;
    destructor Destroy; override;
    property NameCnToEnMap: TListMap<string, string> read FNameCnToEnMap write SetNameCnToEnMap;
    property NameEnToCnMap: TListMap<string, string> read FNameEnToCnMap write SetNameEnToCnMap;
  end;

var
  Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.Button1Click(Sender: TObject);
var
  bb: TBanJi111;
  I: Integer;
  start_miao: Int64;
  response1, response2: string;
begin
  bb := TBanJi111.Create;
  try
    //看下结果
    Memo1.Lines.Clear;
    Memo1.Lines.Add(bb.getNameCnByEn('XiaoLi'));
    Memo1.Lines.Add(bb.getNameEnByCn('李飞刀'));

    //循环测试性能
    start_miao := GetTickCount;
    for I := 0 to 100000 do
    begin
      //通过英文取中文
      response1 := bb.getNameCnByEn('XiaoLi');
      //通过中文取英文
      response2 := bb.getNameEnByCn('李飞刀');
    end;
    Memo1.Lines.Add('总耗时(毫秒): ' + (GetTickCount - start_miao).ToString);
  finally
    bb.Free;
  end;
end;

{ TBanJi }

function TBanJi111.getNameCnByEn(const nameEn: string): string;
var
  MyList: TStringList;
begin
  MyList := TStringList.Create;
  try
    MyList.CommaText := studentNameEnToCnListStr;
    Result := MyList.Values[nameEn];
  finally
    MyList.Free;
  end;
end;

function TBanJi111.getNameEnByCn(const nameCn: string): string;
var
  MyList: TStringList;
  I: Integer;
begin
  MyList := TStringList.Create;
  try
    MyList.CommaText := studentNameEnToCnListStr;
    for I := 0 to (MyList.Count - 1) do
    begin
      if nameCn = MyList.ValueFromIndex[I] then
      begin
        Result := MyList.Names[I];
        Break;
      end;
    end;
  finally
    MyList.Free;
  end;
end;

{ TBanJi2 }

constructor TBanJi222.Create;
var
  I: Integer;
begin
  inherited Create;
  Self.FNameEnToCnList := TStringList.Create;
  Self.FNameCnToEnList := TStringList.Create;
  //把项目逐条加载进来
  Self.FNameEnToCnList.Add('XiaoLi=李飞刀');
  Self.FNameEnToCnList.Add('XiaoWang=王中王');
  Self.FNameEnToCnList.Add('XiaoZhang=张飞');
  //key与value反转写入另一个TStringList
  for I := 0 to Self.FNameEnToCnList.Count - 1 do
  begin
   Self.FNameCnToEnList.Add(Self.FNameEnToCnList.ValueFromIndex[I] + '=' + Self.FNameEnToCnList.Names[I]);
  end;
end;

destructor TBanJi222.Destroy;
begin
  Self.FNameEnToCnList.Free;
  Self.FNameCnToEnList.Free;
  inherited Destroy;
end;

procedure TBanJi222.SetNameCnToEnList(const Value: TStringList);
begin
  FNameCnToEnList := Value;
end;

procedure TBanJi222.SetNameEnToCnList(const Value: TStringList);
begin
  FNameEnToCnList := Value;
end;

procedure TForm5.Button2Click(Sender: TObject);
var
  bb: TBanJi222;
  I: Integer;
  start_miao: Int64;
  response1, response2: string;
begin
  bb := TBanJi222.Create;
  try
    //看下结果
    Memo1.Lines.Clear;
    Memo1.Lines.Add(bb.NameEnToCnList.Values['XiaoLi']);
    Memo1.Lines.Add(bb.NameCnToEnList.Values['李飞刀']);

    //循环测试性能
    start_miao := GetTickCount;
    for I := 0 to 100000 do
    begin
      //通过英文取中文
      response1 := bb.NameEnToCnList.Values['XiaoLi'];
      //通过中文取英文
      response2 := bb.NameCnToEnList.Values['李飞刀'];
    end;
    Memo1.Lines.Add('总耗时(毫秒): ' + (GetTickCount - start_miao).ToString);
  finally
    bb.Free;
  end;
end;

procedure TForm5.Button3Click(Sender: TObject);
var
  bb: TBanJi333;
  I: Integer;
  start_miao: Int64;
  response1, response2: string;
begin
  bb := TBanJi333.Create;
  try
    //看下结果
    Memo1.Lines.Clear;
    Memo1.Lines.Add(bb.NameEnToCnMap['XiaoLi']);
    Memo1.Lines.Add(bb.NameCnToEnMap['李飞刀']);

    //循环测试性能
    start_miao := GetTickCount;
    for I := 0 to 100000 do
    begin
      //通过英文取中文
      response1 := bb.NameEnToCnMap['XiaoLi'];
      //通过中文取英文
      response2 := bb.NameCnToEnMap['李飞刀'];
    end;
    Memo1.Lines.Add('总耗时(毫秒): ' + (GetTickCount - start_miao).ToString);
  finally
    bb.Free;
  end;
end;

procedure TForm5.Button4Click(Sender: TObject);
var
  bb: TBanJi444;
  I: Integer;
  start_miao: Int64;
  response1, response2: string;
begin
  bb := TBanJi444.Create;
  try
    //看下结果
    Memo1.Lines.Clear;
    Memo1.Lines.Add(bb.NameEnToCnMap['XiaoLi']);
    Memo1.Lines.Add(bb.NameCnToEnMap['李飞刀']);

    //循环测试性能
    start_miao := GetTickCount;
    for I := 0 to 100000 do
    begin
      //通过英文取中文
      response1 := bb.NameEnToCnMap['XiaoLi'];
      //通过中文取英文
      response2 := bb.NameCnToEnMap['李飞刀'];
    end;
    Memo1.Lines.Add('总耗时(毫秒): ' + (GetTickCount - start_miao).ToString);
  finally
    bb.Free;
  end;
end;

procedure TForm5.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;
end;

{ TBanJi333 }

constructor TBanJi333.Create;
var
  myKey: string;
begin
  inherited Create;
  Self.FNameEnToCnMap := TDictionary<string, string>.Create();
  Self.FNameCnToEnMap := TDictionary<string, string>.Create();

  //把项目逐条加载进来
  Self.FNameEnToCnMap.Add('XiaoLi', '李飞刀');
  Self.FNameEnToCnMap.Add('XiaoWang', '王中王');
  Self.FNameEnToCnMap.Add('XiaoZhang', '张飞');

  //key与value反转写入另一个TDictionary
  for myKey in Self.FNameEnToCnMap.Keys do
  begin
   Self.FNameCnToEnMap.Add(Self.FNameEnToCnMap[myKey], myKey);
  end;
end;

destructor TBanJi333.Destroy;
begin
  Self.FNameEnToCnMap.Free;
  Self.FNameCnToEnMap.Free;
  inherited Destroy;
end;

procedure TBanJi333.SetNameCnToEnMap(const Value: TDictionary<string, string>);
begin
  FNameCnToEnMap := Value;
end;

procedure TBanJi333.SetNameEnToCnMap(const Value: TDictionary<string, string>);
begin
  FNameEnToCnMap := Value;
end;

{ TBanJi444 }

constructor TBanJi444.Create;
var
  myKey: string;
begin
  inherited Create;
  Self.FNameEnToCnMap := TListMap<string, string>.Create();
  Self.FNameCnToEnMap := TListMap<string, string>.Create();

  //把项目逐条加载进来
  Self.FNameEnToCnMap.Add('XiaoLi', '李飞刀');
  Self.FNameEnToCnMap.Add('XiaoWang', '王中王');
  Self.FNameEnToCnMap.Add('XiaoZhang', '张飞');

  //key与value反转写入另一个TDictionary
  for myKey in Self.FNameEnToCnMap.Keys do
  begin
   Self.FNameCnToEnMap.Add(Self.FNameEnToCnMap[myKey], myKey);
  end;
end;

destructor TBanJi444.Destroy;
begin
  Self.FNameEnToCnMap.Free;
  Self.FNameCnToEnMap.Free;
  inherited Destroy;
end;

procedure TBanJi444.SetNameCnToEnMap(const Value: TListMap<string, string>);
begin
  FNameCnToEnMap := Value;
end;

procedure TBanJi444.SetNameEnToCnMap(const Value: TListMap<string, string>);
begin
  FNameEnToCnMap := Value;
end;

end.
原文地址:https://www.cnblogs.com/del88/p/6760173.html