This topic is now archived and is closed to further replies.


Performance and Type casting

Recommended Posts

all casts except for dynamic_cast have no run-time cost; they are implemented at compile time.

dynamic_cast requires that you enable RTTI (Run-Time Type Information), has a run-time cost and depends on how far away your pointer is from the derived class to which you''re trying to cast. You also must check the return value against NULL in case the cast fails.

Share this post

Link to post
Share on other sites
I think that casting a float to an int might have a small penalty, but nothing to tear your hair over. Likewise, casting between sizes might cause problems. In addition, NEVER do pointer casts that result in losing aligment. That is, make sure that every pointer rests on a memory address that is the module of the data size. In essence, don''t do this:

unsigned long* pl;
unsigned long l[2] = {100,200};
pl = (unsigned long*)((DWORD)&l[1])+1);
unsigned long x = *pl;

Share this post

Link to post
Share on other sites
I do know that casting floats to ints is considered relatively slow by some standard, but I don''t know which. There are many float to int conversion routines written in assembler because of this.

Share this post

Link to post
Share on other sites
dynamic_cast is completely implemented at run time ... so it has a definate cost ... but it''s worth it in the cases that it''s meant to be used.

static_cast has a cost that is totaly relative to the items being cast ... if you implement a point to foobar cast function .. than static_cast calls this function .. which is obviously necessary ... same goes for any static_cast ... even int to float or whatever ... the cost depends on what is needed to do the job

const_cast has no cost EXCEPT that if you are casting AWAY const ... than the compiler cannot use certain optimizations that only work for const objects .. and if you are casting to const than the compiler may not be able to do certain things that are available only to const items ... but these costs are usually very small ...AND they are usually absolutely necessary (meaning you wouldn''t be const casting in a situation where those optimizations were valid anyway).

reinterpret_cast has no run time cost ... except that the compiler obviously generates code after the cast as if it''s the new type ... but once again .. you wouldn''t do it if that''s not what you want ... so the cost is zero.

C style casting has EXACTLY the same cost as the C++ std casts except that you can''t tell which one''s being done at first ... C has no const ... so that''s not needed .. and it has no RTTI so that''s out ... but a line like x = (float) y; or i = (int*) a; is that same as a static cast in the first case (non-pointer) and a reinterpret cast in the second (pointer) ...

there are also the C++ style constructor casts .. like this x = float(y); or pt = 3DPoint(my2DPoint); ... which are almost always exactly the same as a static cast ... but of course in C++ .. you can write diff functions for each ... so they CAN be different .. but usually that would only happen if you make a coding error in one of the functions.

hope that was helpfull...

PS. use c++ casts exclusively if you are trying to learn correctly or want to document what your doing ... they are stricter ... so if you use the right one .. you obviously no what your doing ... whereas people use the C style when they don''t want to think about it .. and hence they are more likely to not realize if there is or isn''t a cost .. or rules they might be violating.

Share this post

Link to post
Share on other sites
Original post by the_grip
Someone correct me if i''m wrong, but a conversion from a float to an int is zero cost except for data (i.e. you lose the precision).

Um, you asked for it ;-)

To conform to the ANSI C/C++ standard, the conversion from float to int has to use truncation for rounding.

Unfortunately the x86 CPU FIST instruction natively uses round to nearest mode - what this means is every time you do something like:

float a = 1.0f;
int b = (int)a;

The compiler bungs in some code (_ftol) which:

- Saves the current control/status word of the FPU (FLDCW)
- Changes the rounding mode of the FPU to truncate
- Does the float to int conversion
- Restores previous FPU control word

As you can probably guess that carries quite a lot of overhead.

Some compilers have an option to ignore ANSI compliance and just replace a cast with an FLD/FIST pair (which can take as little as 1 cycle with latency hiding).

On ones which don''t have the setting, avoid casts between floats and ints or alternatively write your own _ftol to do cheaper rounding (assuming you don''t need to remain compatible with other ANSI compiled things).

Simon O''''Connor
Creative Asylum Ltd

Share this post

Link to post
Share on other sites