timer.cc 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // base/timer.cc
  2. // Copyright 2018 Johns Hopkins University (author: Daniel Povey)
  3. // See ../../COPYING for clarification regarding multiple authors
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  10. // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  11. // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  12. // MERCHANTABLITY OR NON-INFRINGEMENT.
  13. // See the Apache 2 License for the specific language governing permissions and
  14. // limitations under the License.
  15. #include "base/timer.h"
  16. #include "base/kaldi-error.h"
  17. #include <algorithm>
  18. #include <iomanip>
  19. #include <map>
  20. #include <unordered_map>
  21. namespace kaldi {
  22. class ProfileStats {
  23. public:
  24. void AccStats(const char *function_name, double elapsed) {
  25. std::unordered_map<const char*, ProfileStatsEntry>::iterator
  26. iter = map_.find(function_name);
  27. if (iter == map_.end()) {
  28. map_[function_name] = ProfileStatsEntry(function_name);
  29. map_[function_name].total_time = elapsed;
  30. } else {
  31. iter->second.total_time += elapsed;
  32. }
  33. }
  34. ~ProfileStats() {
  35. // This map makes sure we agglomerate the time if there were any duplicate
  36. // addresses of strings.
  37. std::unordered_map<std::string, double> total_time;
  38. for (auto iter = map_.begin(); iter != map_.end(); iter++)
  39. total_time[iter->second.name] += iter->second.total_time;
  40. ReverseSecondComparator comp;
  41. std::vector<std::pair<std::string, double> > pairs(total_time.begin(),
  42. total_time.end());
  43. std::sort(pairs.begin(), pairs.end(), comp);
  44. for (size_t i = 0; i < pairs.size(); i++) {
  45. KALDI_LOG << "Time taken in " << pairs[i].first << " is "
  46. << std::fixed << std::setprecision(2) << pairs[i].second << "s.";
  47. }
  48. }
  49. private:
  50. struct ProfileStatsEntry {
  51. std::string name;
  52. double total_time;
  53. ProfileStatsEntry() { }
  54. ProfileStatsEntry(const char *name): name(name) { }
  55. };
  56. struct ReverseSecondComparator {
  57. bool operator () (const std::pair<std::string, double> &a,
  58. const std::pair<std::string, double> &b) {
  59. return a.second > b.second;
  60. }
  61. };
  62. // Note: this map is keyed on the address of the string, there is no proper
  63. // hash function. The assumption is that the strings are compile-time
  64. // constants.
  65. std::unordered_map<const char*, ProfileStatsEntry> map_;
  66. };
  67. ProfileStats g_profile_stats;
  68. Profiler::~Profiler() {
  69. g_profile_stats.AccStats(name_, tim_.Elapsed());
  70. }
  71. } // namespace kaldi