泛型 for to/in 遍历 PK 效率;TEnumerator、TEnumerable

再使用泛型的时候,经常需要用到遍历功能:

只要继承了 TEnumerator 或 TEnumerable 这两个抽象类的 都具有遍历功能。

当然没有继承这两个抽象类的 也具有使用 for in 来遍历的功能,编译器内置的,具体可以参见万一的博客:

http://www.cnblogs.com/del/archive/2008/11/12/1332011.html

举例:

unit Unit5;

interface

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

type
  TForm5 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  /// <summary>
  /// 定义一个结构体
  /// </summary>
  RPerson = record
    name: string;
    age: Integer;
  end;


var
  Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.Button1Click(Sender: TObject);
var
  mykey,myValue: string;
  MyDic: TDictionary<string, string>;
  MyDic2: TDictionary<string, RPerson>;
  I: Integer;
  person: RPerson;
begin
  MyDic := TDictionary<string, string>.Create();
  MyDic2 := TDictionary<string, RPerson>.Create();
  try
    //初始化
    Memo1.Lines.Clear;
    MyDic.Add('XiaoLi', '李飞刀');
    MyDic.Add('XiaoWang', '王中王');
    MyDic.Add('XiaoZhang', '张飞');

    person.name := '小李飞刀';
    person.age := 10;
    MyDic2.Add('XiaoLi', person);
    person.name := '火云邪神';
    person.age := 50;
    MyDic2.Add('XiaoHuo', person);


    //通过key来遍历
    for mykey in MyDic.Keys do
    begin
      Memo1.Lines.Add(mykey);
    end;
    Memo1.Lines.Add('');


    //通过value来遍历
    for myValue in MyDic.Values do
    begin
      Memo1.Lines.Add(myValue);
    end;
    Memo1.Lines.Add('');


    //通过结构体的值来遍历
    for person in MyDic2.Values do
    begin
      Memo1.Lines.Add(person.name);
    end;
  finally
    MyDic.Free;
    MyDic2.Free;
  end;
end;

end.

可见 遍历 的思想不能 仅仅局限于传统的 for i = 0 to list.cout -1 这种方法,而是应该多用 for in ,for in 可以遍历 一切, 传统的 for 循环  for in 都能实现。

遍历 可以 直接遍历 一切(基本类型、结构体、动态数组、类对象) 既然这样,那么问题 又来了 谁的效率高呢,我们来PK下。

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;

type
  TForm5 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.Button1Click(Sender: TObject);
var
  MyList,tempList1,tempList2: TStringList;
  I: Integer;
  start_time: Int64;
  tempStr: string;
begin
  MyList := TStringList.Create;
  tempList1 := TStringList.Create;
  tempList2 := TStringList.Create;
  try
    //先加进数据来
    for I := 0 to 100000 do
    begin
      MyList.Add(I.ToString);
    end;

    start_time := GetTickCount;
    for I := 0 to MyList.Count - 1 do
    begin
      //只有使用才能看到效果
      tempList1.Add(MyList[I]);
    end;
    Memo1.Lines.Add('fot to 耗时:' + (GetTickCount - start_time).ToString);

    start_time := GetTickCount;
    for tempStr in MyList do
    begin
      //只有使用才能看到效果
      tempList2.Add(tempStr);
    end;
    Memo1.Lines.Add('fot in 耗时:' + (GetTickCount - start_time).ToString);
  finally
    MyList.Free;
    tempList1.Free;
    tempList2.Free;
  end;
end;

end.

效率差不多,其它的就不测试了。 总之以后 不要把思维局限于 for to 而是 多用 for in

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