views:

104

answers:

2

Hi,

Function return values versus "output" parameter, which one is faster? I think I best explain using what I am currently working on.

// specify identifier and return pointer.
SceneNode* createSceneNode(const String& desired_identifier);   // f1

// auto-gen identifier and return as string.
String createSceneNode(SceneNode*& out_ptr_to_creation); // f2

// auto-gen identifier and return pointer to node
SceneNode* createSceneNode(String& out_gen_identifier); // f3

// auto-gen identifier and return as string.
void createSceneNode(SceneNode*& out_ptr_to_creation, String& out_gen_identifier); // f4

While I prefer f1 and f3, because they return SceneNode*, they result in ambiguos call. Furthermore, often, only SceneNode* is required. The String& in f3 will present some inconvenience and overhead, so I am planning on f1 and f2.

My question is, will there be a difference between

f2(node); // return value not assigned.
          // will there be an optimisation NOT to copy string?
mystring = f2(node);

My guess is that function parameter storage should be in some very-fast-access area and will be readily available so output parameters work faster. however, if optimisation is done to prevent copy string in f2, then f2 will be better than f4.

I know in my example, this could be minimal, but I just want to know for knowledge/interest sake.

another side question: I always assume that references are 32bit data and passing reference is as fast as pointers, is that so?

Thanks. =)

+1  A: 

I would use f1 and f3 and simply change the name of one of the functions (for example f1 => createSceneNodeWithId). The semantics of both functions are different enough to warrant different names. I'd avoid a reference to a pointer (SceneNode *&), since it may be a bit confusing.

Returning a String may be slow, so yes, you'd better avoid it and use an output parameter. I don't think the copying can be optimized away unless (a) the function is inlined or (b) your compiler performs a good whole-program analysis. The Intel C++ compiler does that, but I don't know if it will catch this case.

In response to your side question: a reference is really a pointer with different syntax. It will be 32 bits wide on a 32-bit platform, 64 bits on 64-bit platform.

larsmans
A: 

The difference between

mystring = f2(node)

and

f2(node)

are important to understand. In the first case, most compilers will optimize away the copy constructor for returning by value and simply assign the string from the function without the additional copy step. In the case of the second version, most optimizers will do away with any copy or assignment entirely (there's no assignment at all and the copy constructor for return can be optimized away).

Your statement about f2 vs. f4 is accurate. Because of return optimizations, f2 has a good chance of outperforming f4. (I'll add a link to a nice article when I find it.)

Oh, and passing pointers by reference is just fine.

JoshD