【注】QProfile 为 QDAC 4.0 引入的独立单元,所以你可以在项目中直接引用该单元而不会引入其它问题。
QProfile 是一个基于 Delphi 的代码性能跟踪引擎,可以帮助您找到程序中那一部分代码的执行效率。同时,它还会记录您程序中函数调用顺序、调用及递归次数、依赖关系等信息,从而生成函数调用路径分析报告。
当然,做为实现上述功能,QProfile 并非毫无代价,但它的开销很小,您几乎可以放心的在正式运行的代码中启用本功能。
- 占用内存极小,每个线程才会占用一个 IQProfileHelper 接口实现,TQProfile.Calc 会为每个序列重复访问共享第一次创建的实例。
- 同一调用序列,仅在第一次访问时,才会分配内存,后续访问都是直接重用,而不会重新分配,省却重复分配内存时间。
- 尽可能简化处理逻辑,降低函数跟踪分析需要的代码量。
- 在需要完整性能时,程序中可以通过代码来随时禁用跟踪记录功能。
产品用途
- 基于函数的调用次数、执行时间、调用序列等信息,分析代码性能瓶径,找到慢代码,从而进行针对性优化,从而提升产品运行效率。
- 通过分析函数间调用关系,与业务流程进行比对,从而找出问题代码。
- 通过执行函数路径分析,辅助开发人员对函数中无效的路径进行剔除,提升代码质量。
- 并发冲突分析,辅助开发人员在多线程开发中,找到并发函数,以便进行必要的加锁处理,避免并发冲突。
已知问题
- TQProfile 没有编写 IDE 插件来集成到 IDE,暂时不支持自动化为您的代码添加 TQProfile.Calc(函数名) 的代码,需要您自行在需要测试性能的地方调用 TQProfile.Calc 函数。
- TQProfile 为每个线程维护跟踪信息,不同线程的跟踪信息并不会自动合并(当然,您可以对其进行后期处理)。
- TQProfile 不会因为线程被释放,而自动释放该线程对应的跟踪记录,换句话说,如果您的程序在不断的创建/释放线程,而在对应的线程中存在跟踪代码,则会随着每次线程的创建和释放,生成一份除了线程ID不一样,其它内容重复的拷贝。
- TQProfile 在启用状态下,会自动在程序退出时保存跟踪数据到 TQProfile.FileName 属性指定的 json 格式文件中。
基础用法
- 在您项目的搜索路径路径中加入 qdac.profile.pas 单元所在的目录。
- 在您的代码的 uses 指令中,加入 qdac.profile 。
- 为您需要跟踪的函数的开始计时位置,添加 TQProfile.Calc 调用代码。
- 确认 TQProfile.Enabled 为 true 以启用跟踪:
- 调试模式,默认该值为 true
- 命令行参数加入 /EnableProfile 可以强制设置该值为 true
- 用户自己通过设置 TQProfile.Enabled := true 来启用跟踪。
- 编译运行程序,并执行必要的操作。
- 退出程序
- 查看性能和跟踪分析记录文件(默认为程序执行目录下的 profiles.json)
基础示例
...
implementation
uses qdac.profile;
//以上两行,后续示例省略
procedure test();
procedure f1();
begin
TQProfile.Calc('test.f1');
...
end;
begin
TQProfile.Calc('f1');
f1();
end;
输出结果
下面的结果是自带的示例程序的输出结果,具体格式解析,我们在后面进行详细说明。
[
{
"threadId":8740,
"freq":10000000,
"mainThread":true,
"chains":[
{
"name":"TForm1.Button1Click",
"maxNestLevel":0,
"runs":1,
"minTime":0,
"maxTime":782,
"totalTime":782,
"avgTime":782,
"children":[
{
"name":"TForm1.DoProfile",
"maxNestLevel":32,
"runs":1,
"minTime":0,
"maxTime":578,
"totalTime":578,
"avgTime":578
}
]
},
{
"name":"TForm1.Button1Click.ForceQueue#1",
"maxNestLevel":0,
"runs":1,
"minTime":0,
"maxTime":19876018,
"totalTime":19876018,
"avgTime":19876018,
"refs":[
"TForm1.Button1Click"
]
},
{
"name":"TForm1.Button3Click",
"maxNestLevel":0,
"runs":1,
"minTime":0,
"maxTime":856,
"totalTime":856,
"avgTime":856
}
]
},
{
"threadId":7648,
"chains":[
{
"name":"TForm1.DoProfile",
"maxNestLevel":32,
"runs":1,
"minTime":0,
"maxTime":590,
"totalTime":590,
"avgTime":590
}
]
}
]