Benchmark.xs
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:3k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #include "../dense_hash_map.h"
  2. #include "EXTERN.h"
  3. #include "perl.h"
  4. #include "XSUB.h"
  5. #include <stdlib.h>
  6. #include <time.h>
  7. #include <string.h>
  8. #include <vector>
  9. #include <list>
  10. typedef double (*HR_Time_t) ();
  11. static void *HR_Time_p = 0;
  12. #define HR_Time ((HR_Time_t) HR_Time_p)
  13. using namespace std;
  14. using namespace google;
  15. struct Item {
  16. clock_t clock;
  17. double realTime;
  18. Item() {
  19. clock = 0;
  20. realTime = 0;
  21. }
  22. };
  23. struct eqstr {
  24. bool operator()(const char* s1, const char* s2) const {
  25. return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
  26. }
  27. };
  28. typedef dense_hash_map<const char *, int, HASH_NAMESPACE::hash<const char *>, eqstr> StrIntMap;
  29. class Benchmark {
  30. private:
  31. StrIntMap domainToId;
  32. vector<Item *> measurements;
  33. vector<Item *> results;
  34. list<char *> domains;
  35. public:
  36. Benchmark() {
  37. domainToId.set_empty_key(NULL);
  38. }
  39. ~Benchmark() {
  40. vector<Item *>::iterator it;
  41. list<char *>::iterator it2;
  42. for (it = measurements.begin(); it != measurements.end(); it++) {
  43. delete *it;
  44. }
  45. for (it = results.begin(); it != results.end(); it++) {
  46. delete *it;
  47. }
  48. for (it2 = domains.begin(); it2 != domains.end(); it2++) {
  49. free(*it2);
  50. }
  51. }
  52. void begin(const char *domain) {
  53. Item *item;
  54. StrIntMap::iterator result = domainToId.find(domain);
  55. if (result == domainToId.end()) {
  56. char *domainCopy = strdup(domain);
  57. domains.push_front(domainCopy);
  58. domainToId[domainCopy] = measurements.size();
  59. item = new Item();
  60. measurements.push_back(item);
  61. results.push_back(new Item());
  62. } else {
  63. pair<const char *, int> p = *result;
  64. item = measurements[p.second];
  65. }
  66. item->clock = clock();
  67. item->realTime = HR_Time();
  68. }
  69. void end(const char *domain) {
  70. int id = domainToId[domain];
  71. Item *measurement = measurements[id];
  72. Item *result = results[id];
  73. result->clock += clock() - measurement->clock;
  74. result->realTime += HR_Time() - measurement->realTime;
  75. }
  76. const list<char *> getDomains() {
  77. return domains;
  78. }
  79. const Item * getResult(const char *domain) {
  80. int id = domainToId[domain];
  81. return results[id];
  82. }
  83. };
  84. static Benchmark benchmark;
  85. MODULE = Utils::Benchmark PACKAGE = Benchmark
  86. PROTOTYPES: ENABLE
  87. void
  88. init()
  89. CODE:
  90. SV **svp = hv_fetch(PL_modglobal, "Time::NVtime", 12, 0);
  91. if (!svp) {
  92. croak("Time::HiRes is required");
  93. }
  94. if (!SvIOK(*svp)) {
  95. croak("Time::NVtime isn't a function pointer");
  96. }
  97. HR_Time_p = INT2PTR(void *, SvIV (*svp));
  98. void
  99. begin(domain)
  100. char *domain
  101. CODE:
  102. benchmark.begin(domain);
  103. void
  104. end(domain)
  105. char *domain
  106. CODE:
  107. benchmark.end(domain);
  108. SV *
  109. getResults()
  110. CODE:
  111. list<char *>::iterator it;
  112. list<char *> domains;
  113. HV *results;
  114. domains = benchmark.getDomains();
  115. results = (HV *) sv_2mortal((SV *) newHV());
  116. for (it = domains.begin(); it != domains.end(); it++) {
  117. const Item *item = benchmark.getResult(*it);
  118. HV *perl_item = (HV *) sv_2mortal((SV *) newHV());
  119. hv_store(perl_item, "clock", 5, newSViv(item->clock), 0);
  120. hv_store(perl_item, "realTime", 8, newSVnv(item->realTime), 0);
  121. hv_store(results, *it, strlen(*it), newRV((SV *) perl_item), 0);
  122. }
  123. RETVAL = newRV((SV *) results);
  124. OUTPUT:
  125. RETVAL
  126. double
  127. clock2msec(clocktime)
  128. double clocktime
  129. CODE:
  130. RETVAL = clocktime / (double) CLOCKS_PER_SEC;
  131. OUTPUT:
  132. RETVAL