(A)
template <typename T>
metainline foo<T> lerp(const foo<T>& a, const foo<T>& b, const T& time)
{
foo<T> v;
repeat< 4,exec_mul<T> >::exec(v,a,b,t ime);
return v;
}
(B)
template <typename T>
inline foo<T> lerp(const foo<T>& a, const foo<T>& b, const T& time)
{
return foo<T>(
a[0] + (b[0] - a[0]) * time,
a[1] + (b[1] - a[1]) * time,
a[2] + (b[2] - a[2]) * time,
a[3] + (b[3] - a[3]) * time);
}
Which of the above: (A) or (B) is "better" from the viewpoint of the
language police? I am mainly interested in efficiency (assuming correctness
is met in both cases). I'm unrolling repeatitive tasks in (A), but I would
like to know if this is the famous NRVO I keep hearing about ; the return
value is named.. but is (B) theoretically more efficient, excluding possible
overhead from repeat<> template?
Here's the repeat and exec_mul in case they are relevant:
template <typename SCALAR>
struct exec_lerp
{
template <typename A, typename B, typename C>
static metainline void exec(int index, A& a, const B& b, const C& c,
const SCALAR& d)
{
a[index] = b[index] + (c[index] - b[index]) * d;
}
};
template <int SIZE, typename E>
struct repeat
{
enum { INDEX = SIZE - 1 };
template <typename A, typename B, typename C>
static metainline void exec(A& a, const B& b, const C& c)
{
repeat<INDEX,E> ::exec(a,b,c);
E::exec(INDEX,a ,b,c);
}
template <typename A, typename B>
static metainline void exec(A& a, const B& b)
{
repeat<INDEX,E> ::exec(a,b);
E::exec(INDEX,a ,b);
}
template <typename A>
static metainline void exec(A& a)
{
repeat<INDEX,E> ::exec(a);
E::exec(INDEX,a );
}
};
In otherwords, is this case of Named Return Value Optimization? While I am
aware that C++ doesn't recognize such concept, but contemporary compilers do
and this isn't std.c++ but rather generic C++ group I thought to ask here to
learn more: I'm interested in performance (and correctness). The "foo" type
has const and non-const [] operator, through which it accesses the
components, the internal presentation is static array, in most cases like
this:
template <typename SCALAR, int SIZE>
class foo
{
protected:
SCALAR m_v[SIZE];
// ...
};
Ie. is it generally (with current compilers!) prefered to return-by-value
constructing the return value object in return statement, or give it a name
and return?
I posted on same topic few years back on my opinions on my current vector
library, where I named the members:
SCALAR x,y,z,w; // example
These are possible to initialize in constructor using initializers, array
isn't.. but array was recommended back then so I decided to give it a shot
in the current design, so from this point of view it doesn't make any
difference if I try to initialize the object in constructor or just unroll
and initialize components with a template.
Any thoughts? Criticism? Helpful suggestions?
--
"I seen things you couldn't imagine.." - B.B. Warner
"I seen you do the them and it wasn't pretty.." - Anonymous
Comment