fork download
  1. #include <algorithm>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <chrono>
  6.  
  7. static int log10_1(unsigned int num)
  8. {
  9. int ret;
  10. static_assert(sizeof(num) == 4, "expected 32-bit long");
  11. if (num >= 10000)
  12. {
  13. if (num >= 1000000)
  14. {
  15. if (num >= 100000000)
  16. ret = (num >= 1000000000) ? 10 : 9;
  17. else
  18. ret = (num >= 10000000) ? 8 : 7;
  19. }
  20. else
  21. ret = (num >= 100000) ? 6 : 5;
  22. }
  23. else
  24. {
  25. if (num >= 100)
  26. ret = num >= 1000 ? 4 : 3;
  27. else
  28. ret = num >= 10 ? 2 : 1;
  29. }
  30. return ret;
  31. }
  32.  
  33. // write string representation of number `n` into buf and return pointer to terminating null
  34. char* to_str(char* buf, unsigned int n)
  35. {
  36. static const char dig_[] = "0001020304050607080910111213141516171819"
  37. "20212223242526272829303132333435363738394041424344454647484950515253545556575859"
  38. "60616263646566676869707172737475767778798081828384858687888990919293949596979899";
  39. int len = log10_1(n);
  40. char *p = buf + len;
  41. *p-- = 0;
  42. while (n >= 100)
  43. {
  44. unsigned int x = (n % 100) * 2;
  45. n /= 100;
  46. *p-- = dig_[x + 1];
  47. *p-- = dig_[x];
  48. }
  49. if (n >= 10)
  50. {
  51. unsigned int x = n * 2;
  52. *p-- = dig_[x + 1];
  53. *p-- = dig_[x];
  54. }
  55. else
  56. *p-- = (char)('0' + n);
  57. return buf + len;
  58. }
  59.  
  60. // write string representation of number `n` into buf and return pointer to terminating null
  61. char* to_str(char* buf, long n)
  62. {
  63. unsigned int l;
  64. if (n < 0)
  65. {
  66. *buf++ = '-';
  67. l = (unsigned int)(-n);
  68. }
  69. else
  70. l = (unsigned int)n;
  71. return to_str(buf, l);
  72. }
  73.  
  74.  
  75. template <typename T>
  76. void foo(char *buffer, T value)
  77. {
  78. static_assert(std::is_integral<T>::value, "Type of value must be an integral type");
  79.  
  80. if (value < 0) {
  81. *(buffer++) = '-';
  82. }
  83.  
  84. char *start = buffer;
  85.  
  86. while (value != 0) {
  87. *(buffer++) = '0' + std::abs(value % 10);
  88. value /= 10;
  89. }
  90.  
  91. if (buffer == start) {
  92. *(buffer++) = '0';
  93. }
  94. else {
  95. std::reverse(start, buffer);
  96. }
  97.  
  98. *buffer = '\0';
  99. }
  100.  
  101. int main()
  102. {
  103. long ll[3000];
  104. for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
  105. ll[i] = (rand() << 16) | rand() * (rand() > 10000 ? -1 : 1);
  106.  
  107. char buf1[32], buf2[32], buf3[32];
  108.  
  109. for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
  110. {
  111. foo(buf1, ll[i]);
  112. to_str(buf2, ll[i]);
  113. sprintf(buf3, "%d", ll[i]);
  114. if (strcmp(buf1, buf2) || strcmp(buf1, buf3))
  115. printf("error!\n");
  116. }
  117.  
  118. auto start1 = std::chrono::high_resolution_clock::now();
  119. for (int i = 0; i < 10000; ++i)
  120. {
  121. for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
  122. foo(buf1, ll[i]);
  123. } auto finish1 = std::chrono::high_resolution_clock::now();
  124. auto start2 = std::chrono::high_resolution_clock::now();
  125. for (int i = 0; i < 10000; ++i)
  126. {
  127. for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
  128. to_str(buf2, ll[i]);
  129. }
  130. auto finish2 = std::chrono::high_resolution_clock::now();
  131. auto start3 = std::chrono::high_resolution_clock::now();
  132. for (int i = 0; i < 10000; ++i)
  133. {
  134. for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
  135. sprintf(buf3, "%d", ll[i]);
  136. }
  137. auto finish3 = std::chrono::high_resolution_clock::now();
  138.  
  139. long long micro1 = std::chrono::duration_cast<std::chrono::milliseconds>(finish1 - start1).count();
  140. long long micro2 = std::chrono::duration_cast<std::chrono::milliseconds>(finish2 - start2).count();
  141. long long micro3 = std::chrono::duration_cast<std::chrono::milliseconds>(finish3 - start3).count();
  142.  
  143. printf("foo time: %lld ms\n", micro1);
  144. printf("to_str time: %lld ms\n", micro2);
  145. printf("sprintf time: %lld ms\n", micro3);
  146. }
  147.  
Success #stdin #stdout 3.05s 15240KB
stdin
Standard input is empty
stdout
foo time: 745 ms
to_str time: 327 ms
sprintf time: 1989 ms