如何无需重复调用数组值,安全为嵌套循环数组元素添加整数?
优化嵌套循环中数组元素的整数加法方案
嘿,针对你在嵌套循环里给数组元素加整数、想避免重复调用数组值的需求,我给你几个实用的优化方案,兼顾性能和可读性:
1. 复用元素引用(最推荐,平衡性能与可读性)
原代码里重复调用dots.at<Vec3b>(i, j)会带来不必要的函数调用和边界检查开销,我们可以先获取一次元素的引用,之后直接复用:
void box(const Mat &dots, Mat &newdots, int rows, int cols) { // 先确保newdots的尺寸和类型和dots一致 newdots.create(dots.size(), dots.type()); for (int i = 0; i < dots.rows; i++) { for (int j = 0; j < dots.cols; j++) { // 只调用一次at<>()获取引用 const Vec3b& src_pixel = dots.at<Vec3b>(i, j); Vec3b& dst_pixel = newdots.at<Vec3b>(i, j); dst_pixel[0] = src_pixel[0]; dst_pixel[1] = src_pixel[1] + 3; // 给通道1加3 dst_pixel[2] = src_pixel[2] + 5; // 给通道2加5 } } }
这样把原本6次的at<>()调用减少到2次,在几千次循环的场景下,性能提升会很明显,同时代码可读性也没下降。
2. 直接使用指针访问(极致性能)
如果你的循环次数非常多,追求极致性能,可以跳过at<>()的边界检查(前提是你能保证i和j的范围完全合法,不会越界),直接用指针操作内存:
void box(const Mat &dots, Mat &newdots, int rows, int cols) { newdots.create(dots.size(), dots.type()); for (int i = 0; i < dots.rows; i++) { // 获取当前行的起始指针 const uchar* src_row = dots.ptr<uchar>(i); uchar* dst_row = newdots.ptr<uchar>(i); for (int j = 0; j < dots.cols; j++) { // 计算每个像素的起始偏移(Vec3b是3个uchar,所以每个像素占3字节) int pixel_offset = j * 3; dst_row[pixel_offset] = src_row[pixel_offset]; dst_row[pixel_offset + 1] = src_row[pixel_offset + 1] + 3; dst_row[pixel_offset + 2] = src_row[pixel_offset + 2] + 5; } } }
这种方式完全避免了at<>()的函数调用开销,是手动循环里性能最高的写法,但需要注意内存操作的安全性,确保索引不会越界。
3. 利用OpenCV的并行化循环(省心又高效)
其实OpenCV自带了很多优化的矩阵操作工具,如果你不需要手动控制循环的细节,可以用forEach方法,它内部会自动做并行优化(利用多线程),代码也更简洁:
void box(const Mat &dots, Mat &newdots, int rows, int cols) { newdots = dots.clone(); // 先复制原矩阵 // 并行遍历每个像素 newdots.forEach<Vec3b>([](Vec3b& pixel, const int position[]) { pixel[1] += 3; pixel[2] += 5; }); }
这种写法不需要自己写嵌套循环,OpenCV会帮你优化执行效率,尤其是在多核CPU上,性能可能比手动循环还要好。
内容的提问来源于stack exchange,提问作者Hiro
相关产品推荐
相关产品推荐

