Since you claim that the "return" takes longest, the problem may not be in the function itself, but at the site where the returned value is used.
Alas, here's where your code wastes time:
In allocation of the QVector
each time the average is invoked. Presumably it's called repeatedly, so there's no need to have it allocate a new vector each time.
In QVector::operator[]
. It has a bit more overhead than plain array access because there's this pesky isDetached
call done on every call to operator[]
.
In QVector::append
. Not only does it call isDetached
, but also it checks and modifies the length as well.
Note that there's absolutely nothing wrong with returning of your value. It's a trivial operation and takes next to no time. You're doing it OK when it comes to return - and return only. But you don't show us how you use the returned value, so I can't tell you if maybe you're doing something wrong there.
To prevent repeated allocations and operator[]
overhead, you could use a class that keeps a vector ready for reuse, and use a pointer-to-vector's-data instead of using the vector directly.
To make it go any faster would probably require the use of SIMD intrinsics.
class Averager {
QVector<double> m_result;
Q_DISABLE_COPY(Averager)
public:
QVector<double> movingExponentialAverage(const QVector<double> & a, double lambda) {
if (lambda < 0) lambda = 0; else if (lambda > 1) lambda = 1;
m_result.resize(a.size());
double * b = m_result.data();
double lInv = 1-lambda;
for(int i = 1; i < a.size(); ++i) {
b[i] = a[i] * lambda + b[i-1] * l_inv;
}
return m_result;
}
};
void test() {
Averager avg;
QVector<double> src;
while (true) {
update(src);
const QVector<double> & dst = avg.movingExponentialAverage(src, 0.2);
...
}