C++ 14 Apr 2010 20:41:21
C++ dynamic_cast Performance
A performance comparison of the speed of dynamic_cast operations in C++.
Idea from http://www.nerdblog.com/2006/12/how-slow-is-dynamiccast.html, who did not provide any source so I wrote my own more extensive tests.
Sources
- Ticks counted via cycle.h (local mirror)
- Source: speed-dynamic-cast.cpp
Things Tested
- reinterpret_cast on a known type
- virtual function call + reinterpret_cast
- member variable access + reinterpret_cast
- successful dynamic_cast to its own type
- successful dynamic_cast from the derived levels to lower levels
- failed dynamic_cast from the derived levels to an unrelated type
Observations
- dynamic_cast is slow for anything but casting to the base type; that particular cast is optimized out
- the inheritance level has a big impact on dynamic_cast
- member variable + reinterpret_cast is the fastest reliable way to determine type; however, that has a lot higher maintenance overhead when coding
Linux: GNU g++ 4.4.1
- Compiler: GNU g++ 4.4.1 -std=c++0x -O3
- Arch: Linux 2.6.27 x86_64, 2.66GHz Xeon, 8 GiB RAM
| g++ 4.4.1 | Ticks | Relative Factor |
|---|---|---|
| reinterpret_cast known-type | 6008160 | 1.00 |
| virtual function + reinterpret_cast | 11017248 | 1.83 |
| member variable + reinterpret_cast | 8013216 | 1.33 |
| dynamic_cast same-type-base success | 7009392 | 1.17 |
| dynamic_cast same-type-level1 success | 30931008 | 5.15 |
| dynamic_cast same-type-level2 success | 30442688 | 5.07 |
| dynamic_cast same-type-level3 success | 30478432 | 5.07 |
| dynamic_cast level1-to-base success | 6008176 | 1.00 |
| dynamic_cast level2-to-base success | 7009504 | 1.17 |
| dynamic_cast level3-to-base success | 6008176 | 1.00 |
| dynamic_cast level2-to-level1 success | 36055776 | 6.00 |
| dynamic_cast level3-to-level1 success | 43178320 | 7.19 |
| dynamic_cast level3-to-level2 success | 36056256 | 6.00 |
| dynamic_cast onebase-to-twobase fail | 27042336 | 4.50 |
| dynamic_cast onelevel1-to-twobase fail | 33051232 | 5.50 |
| dynamic_cast onelevel2-to-twobase fail | 39096128 | 6.51 |
| dynamic_cast onelevel3-to-twobase fail | 99445824 | 16.55 |
Linux: LLVM clang++
- Compiler: clang++ 1.5 (trunk 101368) -O3
- Arch: Linux 2.6.27 x86_64, 2.66GHz Xeon, 8 GiB RAM
| clang++ 1.5 (trunk 101368) | Ticks | Relative Factor |
|---|---|---|
| reinterpret_cast known-type | 8012000 | 1.00 |
| virtual function + reinterpret_cast | 14019424 | 1.75 |
| member variable + reinterpret_cast | 8011872 | 1.00 |
| dynamic_cast same-type-base success | 7008224 | 0.87 |
| dynamic_cast same-type-level1 success | 59086352 | 7.37 |
| dynamic_cast same-type-level2 success | 66096320 | 8.25 |
| dynamic_cast same-type-level3 success | 122178992 | 15.25 |
| dynamic_cast level1-to-base success | 8012016 | 1.00 |
| dynamic_cast level2-to-base success | 8011968 | 1.00 |
| dynamic_cast level3-to-base success | 8011696 | 1.00 |
| dynamic_cast level2-to-level1 success | 67097680 | 8.37 |
| dynamic_cast level3-to-level1 success | 73105616 | 9.12 |
| dynamic_cast level3-to-level2 success | 74109456 | 9.25 |
| dynamic_cast onebase-to-twobase fail | 29039904 | 3.62 |
| dynamic_cast onelevel1-to-twobase fail | 37056064 | 4.63 |
| dynamic_cast onelevel2-to-twobase fail | 44063616 | 5.50 |
| dynamic_cast onelevel3-to-twobase fail | 106344656 | 13.27 |
Windows: MSVC++ 2010 Express
- Compiler: MSVC++ 2010 Express _SECURE_SCL=0
- Arch: Windows 7 64 bit, 1.83GHz Core2Duo, 4 GiB RAM
| VC++ 2010 | Ticks | Relative Factor |
|---|---|---|
| reinterpret_cast known-type | 6004526 | 1.00 |
| virtual function + reinterpret_cast | 11008470 | 1.83 |
| member variable + reinterpret_cast | 6004570 | 1.00 |
| dynamic_cast same-type-base success | 6004548 | 1.00 |
| dynamic_cast same-type-level1 success | 70743101 | 11.78 |
| dynamic_cast same-type-level2 success | 101736525 | 16.94 |
| dynamic_cast same-type-level3 success | 135299296 | 22.53 |
| dynamic_cast level1-to-base success | 7005790 | 1.17 |
| dynamic_cast level2-to-base success | 6004273 | 1.00 |
| dynamic_cast level3-to-base success | 6004229 | 1.00 |
| dynamic_cast level2-to-level1 success | 117123820 | 19.51 |
| dynamic_cast level3-to-level1 success | 157488947 | 26.23 |
| dynamic_cast level3-to-level2 success | 149076609 | 24.83 |
| dynamic_cast onebase-to-twobase fail | 84984306 | 14.15 |
| dynamic_cast onelevel1-to-twobase fail | 104994120 | 17.49 |
| dynamic_cast onelevel2-to-twobase fail | 130418354 | 21.72 |
| dynamic_cast onelevel3-to-twobase fail | 151142552 | 25.17 |

on 16 Apr 2010 at 14:53:31 1.Jorn said …
It would be nice to see windows tested on a comparable machine
on 16 Apr 2010 at 18:12:56 2.Tino Didriksen said …
I agree, but that would be a lot of extra work…
Right now, I can develop and run the tests simultaneously on my own Windows computer and via SSH on the Linux machine. Having to reboot to Linux just to re-run the tests would be painful. There is also the Cygwin or MinGW options, but while they are nice they really cannot be called a representative picture of how g++ performs.
Plus, the tests I do are not about compiler vs. compiler; they’re about general methods and which ones reliably perform well cross-platform.