fork(1) download
  1. #include <vector>
  2. #include <utility>
  3. #include <cstdio>
  4. #include <cstdint>
  5. #include <cstring>
  6. #include <ctime>
  7.  
  8. enum class ShapeType
  9. {
  10. rectangle = 0,
  11. circle = 1,
  12. triangle = 2,
  13. };
  14.  
  15. struct Shape
  16. {
  17. ShapeType type;
  18. virtual float getarea() = 0;
  19. };
  20.  
  21. struct Rectangle: Shape
  22. {
  23. float x;
  24. float y;
  25. virtual float getarea() override
  26. {
  27. return x * y;
  28. }
  29. };
  30.  
  31. struct Circle: Shape
  32. {
  33. float r;
  34. virtual float getarea() override
  35. {
  36. return 6.2831853072f * r;
  37. }
  38. };
  39.  
  40. struct Triangle: Shape
  41. {
  42. float a;
  43. float b;
  44. float cosp;
  45. virtual float getarea() override
  46. {
  47. return 0.5f * a * b * cosp;
  48. }
  49. };
  50.  
  51. union ShapeUnion
  52. {
  53. Rectangle rectangle;
  54. Circle circle;
  55. Triangle triangle;
  56.  
  57. ShapeUnion()
  58. {
  59. }
  60.  
  61. ShapeUnion( ShapeUnion&& other )
  62. {
  63. memcpy( this, &other, sizeof( ShapeUnion ) );
  64. }
  65.  
  66. ~ShapeUnion()
  67. {
  68. }
  69.  
  70. float getarea_virtual();
  71. float getarea_switch();
  72. };
  73.  
  74. float ShapeUnion::getarea_virtual()
  75. {
  76. Shape* ptr = ( Shape* )this;
  77. return ptr->getarea();
  78. }
  79.  
  80. float ShapeUnion::getarea_switch()
  81. {
  82. switch( ( ( Shape* )this )->type )
  83. {
  84. case ShapeType::rectangle:
  85. return rectangle.getarea();
  86. case ShapeType::circle:
  87. return circle.getarea();
  88. case ShapeType::triangle:
  89. return triangle.getarea();
  90. }
  91. return 0;
  92. }
  93.  
  94. std::vector< ShapeUnion > suv;
  95.  
  96. void fill_vector()
  97. {
  98. suv.resize( 0x1000000 );
  99. for( auto& su: suv )
  100. {
  101. uint32_t n = uintptr_t( &su );
  102. n = ( n << 13 ) ^ n;
  103. n = n * ( n * n * 15731 + 789221 ) + 1376312589;
  104. switch( n % 3 )
  105. {
  106. case 0:
  107. new( &su )Rectangle();
  108. su.rectangle.type = ShapeType::rectangle;
  109. su.rectangle.x = n >> 16;
  110. su.rectangle.y = n & 0xffff;
  111. case 1:
  112. new( &su )Circle();
  113. su.circle.type = ShapeType::circle;
  114. su.circle.r = n;
  115. case 2:
  116. new( &su )Triangle();
  117. su.triangle.type = ShapeType::triangle;
  118. su.triangle.a = n >> 20;
  119. su.triangle.b = ( n >> 8 ) & 0xfff;
  120. su.triangle.cosp = ( n & 0xff ) / 255.0f;
  121. }
  122. }
  123. }
  124.  
  125. void test_virtual()
  126. {
  127. volatile float r;
  128. for( auto& su: suv )
  129. {
  130. r = su.getarea_virtual();
  131. }
  132. ( void )r;
  133. }
  134.  
  135. void test_switch()
  136. {
  137. volatile float r;
  138. for( auto& su: suv )
  139. {
  140. r = su.getarea_switch();
  141. }
  142. ( void )r;
  143. }
  144.  
  145. int main()
  146. {
  147. fill_vector();
  148. clock_t c1 = clock();
  149. for( int i = 0; i < 0x10; ++i )
  150. {
  151. test_virtual();
  152. }
  153. c1 = clock() - c1;
  154. clock_t c2 = clock();
  155. for( int i = 0; i < 0x10; ++i )
  156. {
  157. test_switch();
  158. }
  159. c2 = clock() - c2;
  160. printf( "%li\n%li\n", c1, c2 );
  161. return 0;
  162. }
  163.  
Success #stdin #stdout 4.55s 3456KB
stdin
Standard input is empty
stdout
2029333
1992153