Question

I went to interview for a program job recently and they asked me to write some function that would take a vector and a integer as parameters. The task was to count the number of elements in the vector that were above, below or equal to the integer. I wrote something along these lines:

void printStat(const std::vector<int> &vec, const int &val)
{
    int results[3] = {0,0,0};
    for (int i = 0; i < vec.size(); ++i) {
        int option = (vec[i] == val) ? 0 : ((vec[i] > val) ? 1 : 2);
        results[option]++;
    }
    ...
}

They made a couple of remarks about the code which I found dubious and I'd like to know the opinion of C++ experts. They said that passing vec and val by reference was less efficient than by value. That it would have been better to write:

void printStat(const std::vector<int> vec, const int val) {}

To be honest, I have always written my code using the first version (at the top) and didn't really have the argument to explain why my method would be better or no different than theirs. Their argument was that passing the argument by reference forces later one to dereference the variable when you want its content, which is slower than if I had passed the variable by value.

So my question is: what's the best way, and what would be the reason?

Bonus Question: they also argued that using an iterator in the loop would have been more efficient than using the [] operator to access the element of the vector. I don't see any reason for this, particularly as I suspect that vec[i] will be in the L1 cache when accessed twice in line 5.

Thank you.

Was it helpful?

Solution

It depends on how you will use vec. If you're not having a lot of entries in the vector it's okay to pass it by value as the copying will be pretty quick. But generally it's more "effective" to pass it by reference.

The val argument on the other hand, for native types there is generally no need to pass them as constant references. Actually, as references are often (if not always?) implemented as pointers under the hood, passing this parameter as a reference will on a 64-bit machine pass a 64-bit value compared to a 32-bit value for plain int. And as this is a pointer, it will use extra indirection as well.

OTHER TIPS

Passing objects of built-in types by ref causes extra load. Just use const int val, if you want prevent it from modifications. Using std::vector by ref seems absolutely performant.

I would stick to pass objects by const reference. An exception is, if a copy is made anyway (a const T makes no sense, besides preventing an accidental change in a function implementation).

However: I changed the way to implement operator =.

T& operator=(const T& other) {
   T(other).swap(*this);
   return *this;
}

to

T& operator=(T other) {
   other.swap(*this);
   return *this;
}

to allow copy elision and move semantics.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top