Hello,
j'essaye d'avoir un code simple de benchmarking, mais mon cas semble trop simple et compl�tement optimis� par le compilo...
Voici le code
Rien de fabuleux mais voil� quelques sorties
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 #include <chrono> #include <iostream> struct A { enum class Type { B, C, }; A(Type _t) : type(_t) {} virtual ~A() = 0 {} Type type; template<class T> bool is() const { return T::StaticType == type; } template<class T> bool is_using_dynamic_cast() const { return dynamic_cast<const T*>(this) != nullptr; } template<class T> T* as() { return static_cast<T*>(this); } }; struct B : A { static const Type StaticType = Type::B; B() : A(Type::B) {} size_t value() const { return 1; } }; struct C : A { static const Type StaticType = Type::C; C() : A(Type::C) {} }; int main() { B b; A* a = &b; { size_t n = 0; const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (auto b = dynamic_cast<B*>(a)) { n += b->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with dynamic_cast" << std::endl; } { size_t n = 0; const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (typeid(*a) == typeid(B)) { n += static_cast<B*>(a)->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with typeid" << std::endl; } { size_t n = 0; const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (&typeid(*a) == &typeid(B)) { n += static_cast<B*>(a)->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with &typeid" << std::endl; } { size_t n = 0; const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (a->is_using_dynamic_cast<B>()) { n += a->as<B>()->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with is_using_dynamic_cast (internal dynamic_cast)" << std::endl; } { size_t n = 0; const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (a->is<B>()) { n += a->as<B>()->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with is (enum)" << std::endl; } return 0; }
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5 1479042506 ns with dynamic_cast 541149801 ns with typeid 386570206 ns with &typeid 1355755663 ns with is_using_dynamic_cast (internal dynamic_cast) 256 ns with is (enum)
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5 1479745740 ns with dynamic_cast 536910174 ns with typeid 385768924 ns with &typeid 1392601325 ns with is_using_dynamic_cast (internal dynamic_cast) 0 ns with is (enum)On peut voir que le dernier cas, celui qui m'int�resse particuli�rement, est un peu... rapide ?
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5 1473431996 ns with dynamic_cast 554813324 ns with typeid 384597977 ns with &typeid 1270466484 ns with is_using_dynamic_cast (internal dynamic_cast) 0 ns with is (enum)
Vu que �a implique du template, et que le main est simple, je pense que c'est optimis� et calcul� pendant la compilation...
Du coup j'ai tent� avec un genre de class interm�diaire
La sortie semble plus normale:
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 #include <chrono> #include <iostream> struct A { enum class Type { B, C, }; A(Type _t) : type(_t) {} virtual ~A() = 0 {} Type type; template<class T> bool is() const { return T::StaticType == type; } template<class T> bool is_using_dynamic_cast() const { return dynamic_cast<const T*>(this) != nullptr; } template<class T> T* as() { return static_cast<T*>(this); } }; struct B : A { static const Type StaticType = Type::B; B() : A(Type::B) {} size_t value() const { return 1; } }; struct C : A { static const Type StaticType = Type::C; C() : A(Type::C) {} }; #include <functional> class Checker { public: Checker(std::function<bool(const A*)> _f) : func(_f) {} bool operator()(const A* a) const { return func(a); } private: std::function<bool(const A*)> func; }; int main() { B b; A* a = &b; { size_t n = 0; Checker check([&](const A* a) { return dynamic_cast<const B*>(a) != nullptr; }); const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (check(a)) { n += static_cast<B*>(a)->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with dynamic_cast" << std::endl; } { size_t n = 0; Checker check([&](const A* a) { return typeid(*a) == typeid(B); }); const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (check(a)) { n += static_cast<B*>(a)->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with typeid" << std::endl; } { size_t n = 0; Checker check([&](const A* a) { return &typeid(*a) == &typeid(B); }); const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (check(a)) { n += static_cast<B*>(a)->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with &typeid" << std::endl; } { size_t n = 0; Checker check([&](const A* a) { return a->is_using_dynamic_cast<B>(); }); const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (check(a)) { n += a->as<B>()->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with is_using_dynamic_cast (internal dynamic_cast)" << std::endl; } { size_t n = 0; Checker check([&](const A* a) { return a->is<B>(); }); const auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < 100000000; ++i) { if (check(a)) { n += a->as<B>()->value(); } } const auto end = std::chrono::high_resolution_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); std::cout << elapsed << " ns with is (enum)" << std::endl; } return 0; }
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5 1193004782 ns with dynamic_cast 561807262 ns with typeid 449779071 ns with &typeid 1097718778 ns with is_using_dynamic_cast (internal dynamic_cast) 141872748 ns with is (enum)Et les r�sultats vont dans le sens que j'attends, mais est-ce vraiment probant selon vous ?
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5 1713590819 ns with dynamic_cast 723503932 ns with typeid 553266825 ns with &typeid 1423687229 ns with is_using_dynamic_cast (internal dynamic_cast) 154689676 ns with is (enum)
Merci
Partager