inline关键字是一定要和函数体定义放在一起得,和声明结合是没有作用的。
实现太过简单,以至于他的消耗甚至是小于标准函数调用的消耗,其调用指令相对简单,如果此时我们又需要大量的调用函数,那伴随着的就是大量的指令开销;针对这种浪费情况,“寸土寸金”思想严重的开发人员就设计出了inline函数,又称内联函数。
内联函数最重要的作用就是针对函数调用开销大于函数指令开销的函数体而推出的!实现在编译阶段,将调用开销忽略,直接在函数处进行代码展开,且inline函数也就不会再生成函数符号了!
(1)在debug版本上,inline是无作用的,只有在release版本下才可以!
(2)并非所有的inline函数都会被编译器处理成内联函数 例如递归可以;代码体太过庞大不易展开,要么是代码体是个贪得无厌的无底洞,不能展开;
inline
Mat::Mat(int _rows, int _cols, int _type)
例如
Mat mat(3000,4000,CV_8UC3);
inline
void Mat::create(int _rows, int _cols, int _type)
例如
Mat mat;
mat.create(3000,4000,CV_8UC1);
引用计数为1时才会真正释放
int main(int argc, char* argv) {
Mat image(3000, 4000, CV_8UC3);
int es = image.elemSize();
int size = image.rows * image.cols * es;
for (int i = 0; i < size; i += es) {
image.data[i] = 255;//B
image.data[i + 1] = 0;//G
image.data[i + 2] = 0;//R
}
namedWindow("img");
imshow("img", image);
waitKey(0);
return 0;
}
注:可能因为内存对齐等原因,第一行和第二行不是连续存储的,即第一行末不是第二行开始,而是可能空一些字节用于内存对齐。
int PrintMs(const char *text = "")
{
static long long last = 0;
long long cur = getTickCount();
if (last == 0) {
last = cur;
}
long long ms = ((double)(cur - last) / getTickFrequency()) *1000;
if (*text != 0) {
printf("%s = %d ms\n", text,ms);
}
return 0;
}
优化禁用耗时39ms
优化使速度最大化22ms
注:debug版本开启使速度最大化需要设置:
1.项目属性 c/c+±>优化->使速度最大化
2.c/c+±>常规->调试信息-》程序数据库(/Zi)
3.c/c++ 代码生成->基本运行时检查->默认
for (int row = 0; row < image.rows; row++) {
for (int col = 0; col < image.cols; col++) {
(&image.data[row*image.step])[col*es] = 0;//B
(&image.data[row*image.step])[col*es + 1] = 0;//G
(&image.data[row*image.step])[col*es + 2] = 0;//R
}
}
ptr访问 相比遍历访问 速度更接近于直接地址访问
for (int row = 0; row < image.rows; row++) {
for (int col = 0; col < image.cols; col++) {
Vec3b* c = image.ptr<Vec3b>(row, col);
c->val[0] = 0; //B
c->val[1] = 255; //G
c->val[2] = 0; //R
}
}
try{
//此处rows*2 特意测试异常
for (int row = 0; row < image.rows *2; row++) {
for (int col = 0; col < image.cols; col++) {
Vec3b &m = image.at<Vec3b>(row, col);
m.val[0] = 0; //B
m.val[1] = 255; //G
m.val[2] = 0; //R
}
}
}
catch (cv::Exception &ex) {
std::cout << ex.what() << std::endl;
}
注:Release版本不会抛出异常 只有Debug 会抛出异常
原因:解决try-catch 在RELEASE版无法捕捉错误
auto it = image.begin<Vec3b>();
auto it_end = image.end<Vec3b>();
for (; it != it_end; it++)
{
(*it).val[0] = 0;//B
(*it).val[1] = 0;//G
(*it).val[2] = 255;//R
}
1>可以不用管mat的行列,大小,类型
1>通过地址直接访问 data
2>通过Ptr
3>通过at
4>通过迭代器
具体不展开 后期贴上源码地址