fork(3) download
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <chrono>
  5. #include <set>
  6. #include <ctype.h>
  7.  
  8. template<int ...Is>
  9. struct IntVector{
  10. using Type = IntVector<Is...>;
  11. };
  12.  
  13. template<typename T_Vector, int I_New>
  14. struct PushFront;
  15. template<int ...Is, int I_New>
  16. struct PushFront<IntVector<Is...>,I_New> : IntVector<I_New,Is...>{};
  17.  
  18. template<int I_Size, typename T_Vector = IntVector<>>
  19. struct Iota :
  20. Iota< I_Size-1, typename PushFront<T_Vector,I_Size-1>::Type> {};
  21. template<typename T_Vector>
  22. struct Iota<0,T_Vector> : T_Vector{};
  23.  
  24. template<char C_In>
  25. struct ToUpperTraits {
  26. enum { value = (C_In >= 'a' && C_In <='z') ? C_In - ('a'-'A'):C_In };
  27. };
  28.  
  29. template<typename T>
  30. struct TableToUpper;
  31. template<int ...Is>
  32. struct TableToUpper<IntVector<Is...>>{
  33. static char at(const char in){
  34. static const char table[] = {ToUpperTraits<Is>::value...};
  35. return table[in];
  36. }
  37. };
  38.  
  39. int tableToUpper(const char c){
  40. using Table = TableToUpper<typename Iota<256>::Type>;
  41. return Table::at(c);
  42. }
  43.  
  44. int myToupper ( int c ){
  45. if(c >= 'a' && c <='z'){
  46. return c - ('a'-'A');
  47. }
  48. return c;
  49. }
  50.  
  51. void __attribute__ ((noinline))test1(const std::string& in,std::string& out){
  52. std::transform(in.begin(),in.end(),out.begin(),toupper);
  53. }
  54. void __attribute__ ((noinline))test2(const std::string& in,std::string& out){
  55. std::transform(in.begin(),in.end(),out.begin(),myToupper);
  56. }
  57. void __attribute__ ((noinline))test3(const std::string& in,std::string& out){
  58. std::transform(in.begin(),in.end(),out.begin(),tableToUpper);
  59. }
  60.  
  61. int main() {
  62. std::string s(1024,'.');
  63. std::iota(s.begin(),s.end(),0);
  64. //shuffle (s.begin(), s.end(), std::default_random_engine(1)); //shuffel to make input more realistic
  65. std::string out1(1024,'.');
  66. std::string out2(1024,'.');
  67. std::string out3(1024,'.');
  68.  
  69. std::chrono::nanoseconds time[3]{{},{}};
  70.  
  71. for(int i=0;i<100;i++){
  72. const auto t1 = std::chrono::high_resolution_clock::now();
  73. test1(s,out1);
  74. const auto t2 = std::chrono::high_resolution_clock::now();
  75. time[0] += t2 - t1;
  76. const auto t3 = std::chrono::high_resolution_clock::now();
  77. test2(s,out2);
  78. const auto t4 = std::chrono::high_resolution_clock::now();
  79. time[1] += t4 - t3;
  80. const auto t5 = std::chrono::high_resolution_clock::now();
  81. test3(s,out3);
  82. const auto t6 = std::chrono::high_resolution_clock::now();
  83. time[2] += t6 - t5;
  84. }
  85.  
  86. typedef std::chrono::nanoseconds output_time;
  87. const char* const out_unit = " ns";
  88.  
  89. std::cout << "1: " << std::chrono::duration_cast<output_time>(time[0]).count() << out_unit << "\n";
  90. std::cout << "2: " << std::chrono::duration_cast<output_time>(time[1]).count() << out_unit << "\n";
  91. std::cout << "3: " << std::chrono::duration_cast<output_time>(time[2]).count() << out_unit << "\n";
  92. std::cout << out1[100] << std::endl;
  93. std::cout << out2[100] << std::endl;
  94. std::cout << out3[100] << std::endl;
  95. return 0;
  96. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
1: 1115069 ns
2: 477983 ns
3: 152361 ns
D
D
D