This is a question about a concern I have about choosing between better performance and clearer code (better abstraction) when dealing with arrays. I tried to distill it down to a toy example.

C++ is particularly good at allowing abstractions without hurting performance. The question is whether this is possible in examples similar to the one below.

Consider a trivial arbitrary-size matrix class that uses contiguous row-major storage:

```
#include <cmath>
#include <cassert>

class Matrix {
    int nrow, ncol;
    double *data;
public:
    Matrix(int nrow, int ncol) : nrow(nrow), ncol(ncol), data(new double[nrow*ncol]) { }
    ~Matrix() { delete [] data; }

    int rows() const { return nrow; }
    int cols() const { return ncol; }

    double & operator [] (int i) { return data[i]; }

    double & operator () (int i, int j) { return data[i*ncol + j]; }
};

```

It has a 2D indexing `operator ()` to make it easy to work with. It also has `operator []` for contiguous access, but a better-abstracted matrix may not have this.

Let's implement a function that takes an n-by-2 matrix, essentially a list of 2D vectors, and normalizes each vector in-place.

The clear way:

```
inline double veclen(double x, double y) {
    return std::sqrt(x*x + y*y);
}

void normalize(Matrix &mat) {
    assert(mat.cols() == 2); // some kind of check for correct input
    for (int i=0; i < mat.rows(); ++i) {
        double norm = veclen(mat(i,0), mat(i,1));
        mat(i,0) /= norm;
        mat(i,1) /= norm;
    }
}

```

The fast, but less clear way:

```
void normalize2(Matrix &mat) {
    assert(mat.cols() == 2);
    for (int i=0; i < mat.rows(); ++i) {
        double norm = veclen(mat[2*i], mat[2*i+1]);
        mat[2*i] /= norm;
        mat[2*i+1] /= norm;
    }
}

```

The second version (`normalize2`) has the potential to be faster because it is written in a way that it is clear that the second iteration of the loop will not access data that was computed in the first iteration. Thus it can potentially make better use of SIMD instructions. [Looking at godbolt, this seems to be what happens](https://godbolt.org/g/sMiUHA) (unless I'm misreading the assembly).

In the first version (`normalize`), the compiler can't know that the input matrix is not n-by-1, which would lead to overlapping array accesses.

**Question:** Is it possible to somehow tell the compiler that the input matrix is really n-by-2 in `normalize()` to allow it to optimize to the same level as it does in `normalize2()`?

---

Addressing the comments:

* John Zwinck: I went and did the benchmark. `normalize2()` is considerably faster (2.4 vs 1.3 seconds), but *only if* I remove the `assert` macros or if I define `NDEBUG`. That is a rather counterintuitive effect of `-DNDEBUG`, isn't it? It reduces performance instead of improving it.
* Max: Evidence is both the godbolt output I linked to and the above benchmark. I am also interested in the case when these two functions cannot be inlined (e.g. because they are in a separate translation unit).
* Jarod42 and bolov: This is the answer I was looking for. Confirmed by the benchmark mentioned in the first point. Still, this is important to know in case one implements one's own `assert` (which is exactly what I do in my application).