Repository: opencv
Issue: cv::MatConstIterator performance low
Labels: optimization,category: core,RFC

##### System information (version)
- OpenCV => opencv >=4.5.4
- Operating System / Platform => Linux 64 Bit
- Compiler => Clang 10.0

##### Detailed description
Checked iterators over matrices are slow, and maybe slower than necessary.

##### Steps to reproduce
Iterators can be used to combine cv::Mat objects in a safe way with stl algorithms, that are finding increasing popularity as C++ the community evolves. Slow iterators scare people off, increase the need for features that just re-implement stl algorithms, or simply waste CPU-time. 

In order to reproduce and analyze the issue, I made a test project using google benchmark. 
https://github.com/HattrickGenerator/opencv_iterator_performance_tests

The test just sums up all the elements in the array and let's you choose a data type and the matrix size. The iterators are compared to a standard pointer access (which is of course only valid for contiguous matrices!). cv::Mat holding a floating point type, are not impacted too much by iterator performance, as floating point addition is non associative or commutative, disallowing the compiler to vectorize that operation. For non-floating point types there is however a very clear trend: The raw pointer access is much faster than using the iterators of cv::Mat. This effect is even more pronounced for smaller data types (e.g. uchar instead of int), because the size of an object is getting smaller compared to the word length, while the extra word stays constant.
For a cv::Mat_<int> with a size of 1000 elements, the time for summing up all elements came out to:
using iterators: 1500ns
using pointers: 370ns

Obviously those numbers heavily vary depending on a multitude of factors but the trend is very clear. 

##### Possible solutions
I would like to help resolve this issue. The problematic code paths is especially in mat.inl.hpp:
MatConstIterator& MatConstIterator::operator ++()

1) As a first change I suggest to stop comparing the matrix pointer in iterators in the operator++ and when comparing iterators. It would be possible to change the description for iterator invalidation and UB rules on comparing iterators from different matrix objects (as it is the case for the stl). 
To try this change I made the branch no-matPtr in my project. In my timings this didn't have an effect however:
using iterators: 1480ns
using pointers: 250ns

2) To allow the compiler to optimize the addition 
 if((ptr += elemSize) >= sliceEnd )
more efficiently by making elemSize not depending on a runtime variable. Obviously this is only applicable for the templated versions of a cv::Mat_ where we can write
 if((ptr += sizeof(T)) >= sliceEnd )

In order to simulate this I created the branch no-MatPtr-fixedByteSize in my project. The timings here suggest a benefit
using iterators: 1060
using pointers: 350ns

This however would change the class hirarchy of iterators. It would need to be changed in order for MatConstIterator_ not to derive from MatConstIterator. 

more) There are other ideas to be tested such as runtime dispatch of a operator ++() function, depending on if the matrix is continuous or not.