下表是step6,使用最大的输入样本dict1 (2.6M),测试得到的性能数据。
注意底色是黄色的函数,那些都是主要处理函数。
Add调用了467371次,消耗了1537时间。
TraverseTbl调用1次,消耗了662时间。
getline调用了46731次,消耗了467时间。
这时,Add成为了瓶颈了。
调用次数 | 已用包含时间 | 应用程序包含时间 | |
_wmain | 1 | 2753.604461 | 2753.604461 |
step6(void) | 1 | 2753.604056 | 2753.604056 |
@__security_check_cookie@4 | 1 | 0.000036 | 0.000036 |
@_RTC_CheckStackVars@8 | 1 | 0.000087 | 0.000087 |
__RTC_CheckEsp | 934760 | 6.579788 | 6.579788 |
GetTickCount | 4 | 0.000613 | 0.000613 |
HashMethod1::Add(char *) | 467371 | 1537.746351 | 1537.746351 |
HashMethod1::HashMethod1(void) | 1 | 0.000042 | 0.000042 |
HashMethod1::InitHashTbl(int) | 1 | 22.929616 | 22.929616 |
HashMethod1::TraverseTbl(void (*)(struct tag_WORD_NODE *,class std::basic_ostream<char,struct std::char_traits<char> > &),class std::basic_ostream<char,struct std::char_traits<char> > &) | 1 | 662.531329 | 662.531329 |
std::basic_ifstream<char,struct std::char_traits<char> >::`vbase destructor'(void) | 1 | 0.00279 | 0.00279 |
std::basic_ifstream<char,struct std::char_traits<char> >::basic_ifstream<char,struct std::char_traits<char> >(void) | 1 | 0.005382 | 0.005382 |
std::basic_ifstream<char,struct std::char_traits<char> >::close(void) | 1 | 0.044906 | 0.044906 |
std::basic_ifstream<char,struct std::char_traits<char> >::is_open(void) | 1 | 0.000187 | 0.000187 |
std::basic_ifstream<char,struct std::char_traits<char> >::open(char const *,int,int) | 1 | 0.108456 | 0.108456 |
std::basic_istream<char,struct std::char_traits<char> >::getline(char *,int) | 467371 | 467.522831 | 467.522831 |
std::basic_ofstream<char,struct std::char_traits<char> >::`vbase destructor'(void) | 1 | 0.015522 | 0.015522 |
std::basic_ofstream<char,struct std::char_traits<char> >::basic_ofstream<char,struct std::char_traits<char> >(char const *,int,int) | 1 | 0.341237 | 0.341237 |
std::basic_ofstream<char,struct std::char_traits<char> >::close(void) | 1 | 3.033811 | 3.033811 |
std::basic_ostream<char,struct std::char_traits<char> >::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > & (*)(class std::basic_ostream<char,struct std::char_traits<char> > &)) | 2 | 0.101021 | 0.101021 |
std::basic_ostream<char,struct std::char_traits<char> >::operator<<(unsigned long) | 2 | 1.172693 | 1.172693 |
std::ios_base::eof(void) | 467372 | 26.135002 | 26.135002 |
THUNK:memset | 1 | 0.000115 | 0.000115 |
THUNK:operator new | 1 | 0.002934 | 0.002934 |
继续对Add函数做性能分析,这时标准算法sort成为了瓶颈了。
sort在这里主要用来排序每个单词中的字母,使其字母序排列。在最终的输出中使用字母排序后的单词比较来确定两个单词是不是变位词。
调用次数 | 已用包含时间 | 应用程序包含时间 | |
HashMethod1::Add(char *) | 467371 | 1537.746351 | 1537.746351 |
__RTC_CheckEsp | 467371 | 2.120028 | 2.120028 |
BUF<char>::GetMem(unsigned int) | 934742 | 49.464285 | 49.464285 |
BUF<struct tag_WORD_NODE>::GetMem(void) | 467371 | 27.777791 | 27.777791 |
std::sort<char *>(char *,char *) | 467371 | 1270.894729 | 1270.894729 |
THUNK:strcpy | 934742 | 55.728823 | 55.728823 |
THUNK:strlen | 467371 | 29.619293 | 29.619293 |
关于sort的优化:
第一个思路是:自己编写排序函数。应该会有提高。
第二个思路是:把sort过程移到TraverseTbl中,后续会并行化该程序。初步估计只有TraverseTbl能被并行。