AIX下C/C++函数性能统计实现方法--改进版
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,上一篇实现,是统计了每一次函数调用的层次关系和耗时。如果在函数调用比较多的情况下,更关心的是减少输出,只需要总计的耗时即可。另外如果是后台程序,输出到文件会更好。因此,对程序做了改进。当设置TRACE
千家信息网最后更新 2026年11月01日AIX下C/C++函数性能统计实现方法--改进版#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <string>
#include <sys/time.h>
using std::vector;
using std::map;
using std::string;
using std::clog;
using std::endl;
using std::ofstream;
using std::ostream;
extern "C" void print_trace(const char * const procname);
struct Stat
{
int lvl;
string name;
long stm;
long etm;
long oitv;
Stat(int l, const string& s, long st) : lvl(l), name(s), stm(st), etm(0), oitv(0) {}
};
struct Sum
{
int cnt;
long itv;
Sum() : cnt(0), itv(0) {}
Sum operator+=(long i)
{
++cnt;
itv+=i;
return *this;
}
};
namespace
{
vector<Stat> tracev;
map<string, Sum> itvm;
int clvl = 0;
bool detailf = (getenv("DETAILF")!=NULL);
}
extern "C" void
__func_trace_enter(const char * const proc_name,
const char * const file_name,
const int line_no,
void ** const id)
{
// printf("{ %s (%s:%d) %p %s\n", proc_name, file_name, line_no, id[0], (char*)*id);
struct timeval nowtm;
gettimeofday(&nowtm, NULL);
++clvl;
tracev.push_back(Stat(clvl, string(proc_name)+"() : "+file_name, nowtm.tv_sec * 1000000 + nowtm.tv_usec));
}
extern "C" void
__func_trace_exit(const char * const proc_name,
const char * const file_name,
const int line_no,
void ** const id)
{
// printf("} %s (%s:%d) %p %s\n", proc_name, file_name, line_no, id[0], (char*)*id);
struct timeval nowtm;
int itv;
gettimeofday(&nowtm, NULL);
auto iter = tracev.end() - 1;
while (iter->etm != 0)
--iter;
iter->etm = nowtm.tv_sec * 1000000 + nowtm.tv_usec;
itv = iter->etm - iter->stm - iter->oitv;
itvm[proc_name]+=itv;
for (auto s = tracev.begin(); s!=iter; ++s)
{
if (s->etm == 0)
s->oitv += itv;
}
--clvl;
if (!detailf)
tracev.erase(iter, tracev.end());
if (clvl == 0)
{
print_trace(proc_name);
tracev.clear(); itvm.clear(); }
}
extern "C" void print_trace(const char * const procname)
{
time_t t;
char buf[30];
ofstream logf(getenv("TRACELOG"), std::ios::app);
ostream &log = logf ? logf : clog;
if (detailf)
{
log<<"Detail of "<< procname <<"() :\n";
for (auto s = tracev.begin(); s!=tracev.end(); ++s)
{
log << s->lvl << "\t";
t=s->stm/1000000;
strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", localtime(&t));
log << buf << "." << s->stm % 1000000 << "\t";
t=s->etm/1000000;
strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", localtime(&t));
log << buf << "." << s->etm % 1000000 << "\t";
log << s->etm-s->stm << "\t" << s->oitv << "\t" << s->etm-s->stm-s->oitv << "\t";
log << string(s->lvl-1, ' ') << s->name << "\n";
}
}
log<<"Total of "<< procname <<"() :\n";
for (auto s = itvm.begin(); s!=itvm.end(); ++s)
{
log << s->first << "()\t count "<< (s->second).cnt << "\ttime " << (s->second).itv << "\n";
}
log<<endl;
}
上一篇实现,是统计了每一次函数调用的层次关系和耗时。如果在函数调用比较多的情况下,更关心的是减少输出,只需要总计的耗时即可。另外如果是后台程序,输出到文件会更好。
因此,对程序做了改进。当设置TRACELOG环境变量,则输出到这个环境变量指定的文件中。如果设置了DETAILF,则会输出调用层次关系和每一次的耗时,否则只输出总计时间。
tr.cpp改进后的程序如下。
设置DETAILF后,运行后输出结果如下。
Detail of main() :
1 20170801152000.103879 20170801152000.104034 155 58 97 main() : tt.c
2 20170801152000.103954 20170801152000.103997 43 3 40 f1() : tt.c
3 20170801152000.103958 20170801152000.103961 3 0 3 f2() : tt.c
2 20170801152000.104017 20170801152000.104032 15 3 12 f1() : tt.c
3 20170801152000.104021 20170801152000.104024 3 0 3 f2() : tt.c
Total of main() :
f1() count 2 time 0.000052 s
f2() count 2 time 0.000006 s
main() count 1 time 0.000097 s
输出
程序
变量
层次
文件
环境
函数
统计
一次函数
后台
情况
时间
结果
上一
运行
性能
方法
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
中关村互联网 科技集团
互联网科技工作委员会副主任毛军
厦门中拓互联网络科技有限公司
互联网科技有限公司图片
互联网科技金融
上海挚品互联网科技
智网互联网科技
为想互联网科技
互联网科技博客
美国互联网前沿科技
新华互联网科技校企合作
深圳互联网科技怎么样
深圳前海聚择互联网科技有限公司
小米互联网科技园设置
浙南科技城互联网大厦建设工程
互联网在线教育科技创业
四川慕妮娅互联网科技有限公司
互联网公司高科技产品
互联网科技实习生岗位
2021世界互联网领先科技成果发布
互联网金融 金融科技
互联网金融科技平台
互联网高科技企业
左右互联网络科技
华中科技有哪些互联网大佬
以后互联网后是啥科技
互联网时代科技改变生活
佳云科技和互联网广告
岳阳华臻互联网科技有限公司
互联网科技包装股