google搜索 站内搜索                 软件测试门户 | 软件测试培训 | 文章资料精选 | 软件测试论坛 | 测试解决方案 | 软件测试博客 | 测试招聘求职 
打印

[转贴] 自己写的一个测试函数执行效率的单元(test on Delphi 7)

自己写的一个测试函数执行效率的单元(test on Delphi 7)


运用了一点技巧来实现对函数进行效率测试

使用方法:
uses
  Profile;
.......

function TForm1.Func1():string;
begin
    TFunctionTimeProfiler.ExecuteTest(ClassName, 'Func1'); //这里会创建一个接口实例,并开始测试; 此实例会自动释放并结束测试
    ....
end;

程序最后退出会自动生成一详细的报告, 根据报告, 就可以有针对性的优化代码, 提高程序的执行效率

希望大家看后能有一点收获



unit Profile;

interface

uses
  SysUtils, Classes, Windows, Controls, Forms;

{$IFNDEF TIMEPROFILE}
  {$DEFINE TIMEPROFILE} { 需要测试时去掉"."即可 }
{$ENDIF}

type
  { 性能测试对象 }
  TTimeProfiler = class(TObject)
  private
    {$IFDEF TIMEPROFILE}
    FItemList, FHistoryList: TStringList;
    FLogStream: TFileStream;
    FLevel: Integer;
    FTimeID: Integer;
    function RecordToString(ClassName, Method: string; Tick: Cardinal): string;
    procedure StringToRecord(Str: string; var ClassName, Method: string; var Tick: Cardinal);
    function Ident: string;
    procedure AddString(s: string; WithBreak: Boolean = True);
    procedure AddHR(CH: Char = '-'; Width: Integer = 80);
    procedure AddBR;
    function GetItem(TestID: Integer): string;
    {$ENDIF}
  public
    constructor Create(LogName: string);
    destructor Destroy; override;
    { 开始测试 }
    function BeginTest(ClassName: string; Method: string): Integer;
    { 结束测试 }
    function EndTest(TestID: Integer): Cardinal;
  end;

  { 性能测试接口,利用接口技术实现自动释放 }
  ITimeProfiler = interface
    ['{4F54512F-728C-438E-9CAE-A10257A58439}']
  end;

  { 函数性能测试对象 }
  TFunctionTimeProfiler = class(TInterfacedObject, ITimeProfiler)
  private
    FTimeID: Integer;
  public
    constructor Create(TimeID: Integer);
    destructor Destroy; override;
    class function ExecuteTest(ClassName: string; Method: string): ITimeProfiler;
  end;

var
  TimeProfiler: TTimeProfiler;

implementation

function iif(const Condition: Boolean; const IfTrue: string; const IfFalse: string): string;
begin
  if Condition then
    Result := IfTrue
  else
    Result := IfFalse;
end;

{ TTimeProfiler }

constructor TTimeProfiler.Create(LogName: string);
begin
  {$IFDEF TIMEPROFILE}
  FTimeID := 0;
  FLevel := 0;
  FItemList := TStringList.Create;
  FHistoryList := TStringList.Create;
  LogName := Trim(LogName);
  if FileExists(LogName) then
  begin
    FLogStream := TFileStream.Create(LogName, fmOpenWrite);
    FLogStream.Seek(0, soFromEnd);
  end
  else
    FLogStream := TFileStream.Create(LogName, fmCreate);
  AddBR;
  AddHR;
  AddString(Format(' 软件性能测试 - 测试时间:%s ', [DateTimeToStr(Now)]));
  AddHR;
  {$ENDIF}
end;

destructor TTimeProfiler.Destroy;
{$IFDEF TIMEPROFILE}
var
  i: Integer;
  ClassName, Method: string;
  Tick: Cardinal;
{$ENDIF}
begin
  {$IFDEF TIMEPROFILE}
  { 保存综合测试结果 }
  if FHistoryList.Count > 0 then
  begin
    AddBR;
    AddHR('*');
    AddString(' 所有函数测试结果(按所花费时间排序) ');
    AddHR('*');
    FHistoryList.Sort;
    for i := FHistoryList.Count - 1 downto 0 do
    begin
      StringToRecord(FHistoryList, ClassName, Method, Tick);
      AddString(ClassName + iif(ClassName <> '', '.', '') + Method + ' - Used Time: ' + Format('%.3f', [Tick / 1000]) + ' sec.');
    end;
  end;
  AddBR;
  AddHR;
  AddString(Format(' 软件性能测试 - 测试结束,时间:%s ', [DateTimeToStr(Now)]));
  AddHR;
  if Assigned(FItemList) then
    FreeAndNil(FItemList);
  if Assigned(FHistoryList) then
    FreeAndNil(FHistoryList);
  if Assigned(FLogStream) then
    FreeAndNil(FLogStream);
  {$ENDIF}
  inherited Destroy;
end;

function TTimeProfiler.BeginTest(ClassName, Method: string): Integer;
begin
  {$IFDEF TIMEPROFILE}
  Inc(FTimeID);
  FItemList.AddObject(RecordToString(ClassName, Method, GetTickCount), Pointer(FTimeID));
  AddString(Ident + ClassName + iif(ClassName <> '', '.', '') + Method + ' - Begin');
  Inc(FLevel);
  Result := FTimeID;
  {$ELSE}
  Result := 0;
  {$ENDIF}
end;

function TTimeProfiler.EndTest(TestID: Integer): Cardinal;
{$IFDEF TIMEPROFILE}
var
  ClassName, Method, s: string;
  Tick: Cardinal;
{$ENDIF}
begin
  {$IFDEF TIMEPROFILE}
  s := GetItem(TestID);
  if s = '' then
    Exception.Create('Cannot end the test ' + IntToStr(TestID) + '!');
  StringToRecord(s, ClassName, Method, Tick);
  Result := GetTickCount - Tick;
  FItemList.Delete(FItemList.Count - 1);
  Dec(FLevel);
  AddString(Ident + ClassName + iif(ClassName <> '', '.', '') + Method + ' - End (Used Time: ' + Format('%.3f', [Result / 1000]) + ' sec.)');
  //if FLevel = 0 then //只保存第一级测试结果
    FHistoryList.Add(RecordToString(ClassName, Method, Result));
  {$ELSE}
  Result := 0;
  {$ENDIF}
end;

{$IFDEF TIMEPROFILE}
function TTimeProfiler.RecordToString(ClassName, Method: string;
  Tick: Cardinal): string;
begin
  Result := Format('%-.8d|%s.%s', [Tick, ClassName, Method]);
end;

procedure TTimeProfiler.StringToRecord(Str: string; var ClassName,
  Method: string; var Tick: Cardinal);
begin
  Tick := StrToIntDef(GetShortHint(Str), 0);
  Str := StringReplace(GetLongHint(Str), '.', '|', [rfReplaceAll]);
  ClassName := GetShortHint(Str);
  Method := GetLongHint(Str);
end;

procedure TTimeProfiler.AddString(s: string; WithBreak: Boolean);
begin
  if Assigned(FLogStream) then
  begin
    if WithBreak then
      s := s + #13#10;
    FLogStream.WriteBuffer(Pointer(s)^, Length(s));
  end;
end;

function TTimeProfiler.Ident: string;
begin
  Result := StringOfChar(' ', FLevel * 4);
end;

procedure TTimeProfiler.AddHR;
begin
  AddString(StringOfChar(CH, Width));
end;

procedure TTimeProfiler.AddBR;
begin
  AddString(#13#10, False);
end;

function TTimeProfiler.GetItem(TestID: Integer): string;
var
  i: Integer;
begin
  Result := '';
  if FItemList.Count > 0 then
  begin
    {
    if TestID = -1 then
    begin
      Result := FItemList[FItemList.Count - 1];
      Exit;
    end;
    }
    for i := FItemList.Count - 1 downto 0 do
      if Integer(FItemList.Objects) = TestID then
      begin
        Result := FItemList;
        Break;
      end;
  end;
end;
{$ENDIF}

{ TFunctionTimeProfiler }

constructor TFunctionTimeProfiler.Create(TimeID: Integer);
begin
  FTimeID := TimeID;
end;

destructor TFunctionTimeProfiler.Destroy;
begin
  TimeProfiler.EndTest(FTimeID);
  inherited Destroy;
end;

class function TFunctionTimeProfiler.ExecuteTest(ClassName: string;
  Method: string): ITimeProfiler;
begin
  {$IFDEF TIMEPROFILE}
  Result := TFunctionTimeProfiler.Create(TimeProfiler.BeginTest(ClassName, Method));
  {$ELSE}
  Result := nil;
  {$ENDIF}
end;

initialization
  if not Assigned(TimeProfiler) then
    TimeProfiler := TTimeProfiler.Create(ChangeFileExt(Application.ExeName, '.Time.txt'));

finalization
  if Assigned(TimeProfiler) then
    FreeAndNil(TimeProfiler);

end.

TOP

好 东东  顶了
....思考中....思考中....希望是在实现中!
技术:http://www.51testing.com/?138861
生活:http://12sin.blog.163.com/
经济:即将上市!

TOP

本功能由奇虎搜索实现

相关主题

标题 作者 最后发表
测试生活 默默巫1 2008-11-06
通信软件白盒测试的三种境界 8002tacylf 2008-08-25
网络游戏测试过程 尛蟲蟲 2008-10-06
防范黑客木马 阿七 2008-08-21
点击阅读更多关于的相关帖子  更多相关主题
 
当前时区 GMT+8, 现在时间是 2008-12-5 16:05Copyright(C)上海博为峰软件技术有限公司 2001-2007 电话:021-64471599-8017
当您在访问网站、论坛及博客过程中遇到问题时可发送email:webmaster@51testing.com或发送论坛短信至管理员风在吹