用一维指针好一些还是二维指针好一些?下标运算真的比指针慢?
如题,如果用二维指针表示图像数据,图像中的任何象素可以直接用一个Pixel[y][x]表示,而不必像一维一样pixel[y*iWidth+x],要经过一个加法和乘法才能获得,并且感觉很直观。
在处理图像数据时,每次循环就不需要再计算y*iWidth+x的值了,感觉效率高点。
先看下面这段代码,功能是从宽为src->width,高为src->height的图像数据中截取出宽为out->width,高为out->height的图像数据,而start_x和start_y指的是图像out的左上角点在图像src中的坐标:
- C/C++ code
for (y = 0; y < out->height; ++y) { for (x = 0; x< out->width; ++x) { /* 计算图片内需要读取的区域的各像素点的位置 */ temp = (start_y + y) * src->width + start_x + x; out->rgba[0][count] = src->rgba[0][temp]; out->rgba[1][count] = src->rgba[1][temp]; out->rgba[2][count] = src->rgba[2][temp]; ++count; } }
图像数据用二维指针表示,第一维有3个,我将图像中的每个像素点的red,green,blue这三种颜色分开存储了,方便以后单独调整图像的颜色。
而第二维,是存储整个图像中每个像素点的数据的,需要通过计算y * width + x的值才能得到点(x,y)在这数据中的位置,也就是只用一维来表示这整个图像数据,本打算用三维指针的,像这样:
- C/C++ code
for (y = 0; y < out->height; ++y) { for (x = 0; x< out->width; ++x) { xx = start_x + x; yy = start_y + y; out->rgba[0][y][x] = src->rgba[0][yy][xx]; out->rgba[1][y][x] = src->rgba[1][yy][xx]; out->rgba[2][y][x] = src->rgba[2][yy][xx]; } }
直接给出点的坐标(xx,yy)就可以了,不需要再计算temp = (start_y + y) * src->width + start_x + x; 。
在使用realloc函数扩增图像数据使用的内存时,只需要在图像的每一行使用realloc函数就可以了,并且,扩增后,即使将图像显示出来,原来尺寸的图像也不变,只是多出来的区域的内容有问题。
代码如下:
- C/C++ code
out->rgba[0] = (unsigned char **)realloc(out->rgba[0], out->height * sizeof(unsigned char*)); out->rgba[1] = (unsigned char **)realloc(out->rgba[1], out->height * sizeof(unsigned char*)); out->rgba[2] = (unsigned char **)realloc(out->rgba[2], out->height * sizeof(unsigned char*)); for (y = 0; y < out->height; ++y) { out->rgba[0][y] = (unsigned char *)realloc(out->rgba[0][y], out->width * sizeof(unsigned char)); out->rgba[1][y] = (unsigned char *)realloc(out->rgba[1][y], out->width * sizeof(unsigned char)); out->rgba[2][y] = (unsigned char *)realloc(out->rgba[2][y], out->width * sizeof(unsigned char)); }
如果只用一维指针表示图像数据,那就需要使用realloc函数将整个图像数据占用的内存扩大,显示出来的话,整个图像都是乱的,要达到和前面那种方法的效果,在扩增内存前,备份一次图像数据,扩增内存后,重新写入。
还有,下标运算真的比指针慢?
看这帖:http://bbs.chinaunix.net/thread-1716792-1-1.html
有人说了编译器会优化,有人说在不同的CPU上,效果也不一样。
也有人说:t[mid] 比 *p 多做了一次乘法运算和一次加法运算。
那上面给出的代码,每次循环是不是需要进行很多次乘法运算和加法运算?
[解决办法]
一样的 你用[y][x]和[y*x+x] 效率一样的 因为[][]对于机器来说 内存可没有2维的 还是需要X累加过去
[解决办法]
另 下标操作和指针+X 没啥区别
[解决办法]
我觉得不用死扣这个吧,下标运算,实际上就是指针的运算。两者效率不会差多少,因为产生的执行代码基本是相同的。我觉得优化的地方是每次循环中的下标(或者是指针的偏移量)是不是有方法更快的计算出,而不是每次循环中都去做这样的事。还有就是算法的优化。
语言运算的优化是要到最后才考虑的。
[解决办法]
你不做,可是编译器需要做这个操作哦!
[解决办法]
你申请的一段内存始终是一维的,可以用C++的class写个2维的类来直观表示
[解决办法]
你做和编译器做
[解决办法]
realloc 放循环里是慢的主要因素。
像这种循环扩大或者减小内存,不仅耗资源,也费时间。一般不会采用这种做法吧.....
图像存成1维的个人感觉速度会好一些,存二维比较直观。
但是按照底层实现上来说个人感觉都是寻址,二维的寻址和你乘法+偏移应该是差不多的(除非二维的寻址,在底层硬件有直接的指令)。
当然,我没有验证过。等高人解答。
[解决办法]
用一维快,因为C++里编译器只认一维,你用二维的话编译器还得转换成一维的
[解决办法]
在循环里面的化,指针大概要快点,每次指针++,但是[n]是每次从头部+n,如果n比较大会有差异,二维的化差异会更大,因为你要乘了再加,而指针直接++