Did performance hit the C ++ style?

I am new to C ++ style styles, and I am worried that using C ++ style styles will result in a loss of performance of my application because I have an urgent critical deadline in my routine interrupt procedure.

I heard some throws even throw exceptions!

I would like to use C ++ style casts because this will make my code more β€œreliable”. However , if there is any kind of performance hit , then I probably won’t use C ++ style casts and instead spend more time testing code that uses C style casts.




Have you done any rigorous tests / profiling to compare the performance of C ++ style applications with C style castes?

What were your results?

What conclusions did you draw?

+44
c ++ performance casting
Mar 23 '09 at 19:50
source share
7 answers

If a C ++ style cast can be conceptually replaced with a C style, then there will be no overhead. If it cannot, as in the case of dynamic_cast , for which there is no C-equivalent, you must pay the cost one way or another.

The following code is an example:

 int x; float f = 123.456; x = (int) f; x = static_cast<int>(f); 

generates identical code for both casts with VC ++ - code:

 00401041 fld dword ptr [ebp-8] 00401044 call __ftol (0040110c) 00401049 mov dword ptr [ebp-4],eax 

The only C ++ is the tide that can throw, dynamic_cast when cast to a link. To avoid this, draw a pointer that will return 0 if a failure occurs.

+77
Mar 23 '09 at 19:54
source share
β€” -

The only one that has the extra cost at runtime is dynamic_cast , which has features that cannot be directly reproduced using a C-style cast anyway. Therefore, you have no problem.

The easiest way to verify this is to instruct your compiler to generate assembler output and examine the code it creates. For example, in any program compiler that consists of strict mode, reinterpret_cast will completely disappear, because it simply means "go blindly forward and pretend that the data is of this type."

+39
Mar 23 '09 at 19:52
source share

Why would a performance hit? They perform the same functionality as C cast. The only difference is that they absorb more errors during compilation and are easier to find in the source code.

static_cast<float>(3) is exactly equivalent to (float)3 and will generate exactly the same code.

Given a float f = 42.0f reinterpret_cast<int*>(&f) is exactly equivalent to (int*)&f and will generate exactly the same code.

And so on. The only difference other than dynamic_cast , which, yes, can throw an exception. But this is because he does what C-style cannot do. Therefore, do not use dynamic_cast unless you need its functions.

It is usually safe to assume that compilers are intelligent. Given two different expressions that have the same semantics according to the standard, it is usually safe to assume that they will be implemented identically in the compiler.

Sorry . The second example should be reinterpret_cast, not dynamic_cast, of course. Corrected.

Well, just to make it absolutely clear, this is what the C ++ standard says:

Β§5.4.5:

Conversions Performed

  • a const_cast (5.2.11)
  • a static_cast (5.2.9)
  • a static_cast followed by const_cast
  • a reinterpret_cast (5.2.10) or
  • a reinterpret_cast followed by const_cast .

can be performed using an explicit type conversion notation. The same semantic restrictions and behavior. If the transformation can be interpreted in more than one of the methods listed above, the interpretation that appears first in the list is used, even if the cast as a result of this interpretation is poorly formed.

So, if something, since the C-style cast is implemented in terms of C ++ translations, the C-style should be slower. (Of course, this is not so, because the compiler generates the same code anyway, but it is more believable than a C ++-style cast slower.)

+16
Mar 23 '09 at 20:11
source share

There are four C ++ style styles:

  • const_cast
  • static_cast
  • reinterpret_cast
  • dynamic_cast

As already mentioned, the first three are compile time operations. There is no penalty time for their use. These are messages to the compiler that data that was declared in one way must be accessible in another way. "I said it was int* , but let me access it as if it were a char* pointing to sizeof(int) char s" or "I said that this data is read-only, and now I need to pass it which will not change it, but does not accept the parameter as a reference to a constant. "

Besides distorting the data by customizing to the wrong type and enumerating the data (always possible using the C-style), the most common runtime problem with these casts is the data that is actually declared const , which may not be closed non-const. Bringing something declared const to non-constant, and then changing it undefined. Undefined means you are not even guaranteed to get a crash .

dynamic_cast is a runtime construct and should have a runtime cost.

The value of these castings lies in the fact that they specifically say what you are trying to do from / in, expose visually and you can search for them using brain tools. I would recommend using them using C-style styles.

+15
Mar 23 '09 at 21:10
source share

When using dynamic_cast , several checks are made at runtime so that you don't do something stupid (more on the GCC mailing list ) the cost of one dynamic_cast depends on how many classes are affected, which classes are affected, etc.
If you are really sure the cast is safe, you can still use reinterpret_cast .

+4
Mar 23 '09 at 20:09
source share

Although I agree with the statement β€œonly at any extra cost during dynamic_cast execution,” keep in mind that there may be differences in compilers.

I saw several errors filed against my current compiler, where the generation or optimization of the code was slightly different depending on whether you use the C-style and C ++ static_cast .

So, if you are worried, check the disassembly in hot spots. Otherwise, just avoid dynamic throws when you don't need them. (If you disable RTTI, you cannot use dynamic_cast in any way.)

+3
Mar 23 '09 at 20:35
source share

Canonical truth is assembly, so try both and see if you have any other logic.

If you get the same assembly, there is no difference - it cannot be. The only place you really need to stick with old C castes is pure C routines and libraries, where it makes no sense to introduce a C ++ dependency only for type casting.

One thing to be aware of is that throws occur everywhere in a decent code size. Throughout my career, I have never looked for β€œall throws” in logic - you tend to look for castings for a certain TYPE of type β€œA”, and searching for β€œ(A)” is usually as effective as something like β€œstatic_cast <A > ". Use new roles for things like type checking, etc., And not because they search, you will never make it easier.

+1
Jul 21 '14 at 14:45
source share



All Articles