`

【测速】矩阵翻转

    博客分类:
  • C++
 
阅读更多
在微博中看到有人分享了篇文章“为什么转置512×512矩阵,会比513×513矩阵慢很多?”http://note.sdo.com/u/1557869253/n/sSPb5~k5HYUMLX0mU000QX
没仔细看原理,但与缓存的命中率有关。
今天写矩阵翻转的代码,突然想到这个问题。测了一下速度:

结论:新建一片内存,顺序访问其中的元素,速度比较快!!!在翻转中能快个两倍左右!!!(注:我的矩阵是行优先存储的)


有关代码如下(代码不完全):
	//水平翻转矩阵中的元素
	void flipHorizontally(){
		T tmp;
		//int halfHeight=height_row/2;
		int halfWidth=width_col/2;
		for (int r=0; r<height_row; r++) {
			for (int c=0; c<halfWidth; c++) {
				int c2=width_col-1-c;
				tmp=getValue(r,c);
				this->operator()(r,c)=this->operator()(r,c2);
				this->operator()(r,c2)=tmp;
			}
		}

	}

	//水平翻转矩阵中的元素
	Matrix flipHorizontallyNewMatrix(){
		Matrix flipped(height_row,width_col);
		int halfWidth=width_col/2;
		for (int r=0; r<height_row; r++) {
			for (int c=0; c<=halfWidth; c++) {
				int c2=width_col-1-c;
				flipped(r,c)=this->operator()(r,c2);
				flipped(r,c2)=this->operator()(r,c);
			}
		}
		return flipped;
	}

	//水平翻转矩阵中的元素
	Matrix flipHorizontallyNewMatrix2(){
		Matrix flipped(height_row,width_col);
		for (int r=0; r<height_row; r++) {
			for (int c=0; c<width_col; c++) {
				int c2=width_col-1-c;
				flipped(r,c)=this->operator()(r,c2);
			}
		}
		return flipped;
	}


	//垂直翻转矩阵中的元素
	Matrix flipVerticallyNewMatrix(){
		Matrix flipped(height_row,width_col);
		int halfHeight=height_row/2;
		for (int r=0; r<=halfHeight; r++) {
			for (int c=0; c<width_col; c++) {
				int r2=height_row-1-r;
				flipped(r,c)=this->operator()(r2,c);
				flipped(r2,c)=this->operator()(r,c);
			}
		}
		return flipped;
	}

	//垂直翻转矩阵中的元素
	Matrix flipVerticallyNewMatrix2(){
		Matrix flipped(height_row,width_col);
		for (int r=0; r<height_row; r++) {
			for (int c=0; c<width_col; c++) {
				int r2=height_row-1-r;
				flipped(r,c)=this->operator()(r2,c);
				//flipped(r2,c)=this->operator()(r,c);
			}
		}
		return flipped;
	}


	//垂直翻转矩阵中的元素
	void flipVertically(){
		T tmp;
		int halfHeight=height_row/2;
		for (int r=0; r<halfHeight; r++) {
			for (int c=0; c<width_col; c++) {
				int r2=height_row-1-r;
				tmp=getValue(r,c);
				this->operator()(r,c)=this->operator()(r2,c);
				this->operator()(r2,c)=tmp;
			}
		}

	}




测试用的代码如下(代码不完全):
        for (int n=10; n<1000; n+=33) {


            MatrixInt m(n,n);
            for (int i=0; i<m.getNumEl(); i++) {
                m(i)=i;
            }

            int testNum=10000/n*10000/n;
            Timer timer;

            for(int i=0; i<testNum; i++)
                m.flipVerticallyNewMatrix();
            long tv1=timer.getElapsedTimeAndRestart();

            for(int i=0; i<testNum; i++)
                m.flipVerticallyNewMatrix2();
            long tv2=timer.getElapsedTimeAndRestart();

			for(int i=0; i<testNum; i++)
				m.flipVertically();
			long tvInplace=timer.getElapsedTimeAndRestart();

            for(int i=0; i<testNum; i++)
                m.flipHorizontallyNewMatrix();
            long th1=timer.getElapsedTimeAndRestart();

            for(int i=0; i<testNum; i++)
                m.flipHorizontallyNewMatrix2();
            long th2=timer.getElapsedTimeAndRestart();

			for(int i=0; i<testNum; i++)
				m.flipHorizontally();
			long thInplace=timer.getElapsedTimeAndRestart();
			cout<<"矩阵大小: "<<m.height_row<<"行*"<<m.width_col<<"列"<<endl;
			cout<<"水平翻转耗时:方法1:  "<<th1<<";\t\t方法2:  "<<th2<<";\t\t原位翻转:  "<<thInplace<<endl;
			cout<<"垂直翻转耗时:方法1:  "<<tv1<<";\t\t方法2:  "<<tv2<<";\t\t原位翻转:  "<<tvInplace<<endl;
            cout<<endl;

        }



测试用结果如下:
矩阵大小: 10行*10列
水平翻转耗时:方法1:  566;		方法2:  340;		原位翻转:  410
垂直翻转耗时:方法1:  652;		方法2:  342;		原位翻转:  450

矩阵大小: 43行*43列
水平翻转耗时:方法1:  364;		方法2:  180;		原位翻转:  390
垂直翻转耗时:方法1:  425;		方法2:  178;		原位翻转:  434

矩阵大小: 76行*76列
水平翻转耗时:方法1:  361;		方法2:  188;		原位翻转:  402
垂直翻转耗时:方法1:  433;		方法2:  183;		原位翻转:  445

矩阵大小: 109行*109列
水平翻转耗时:方法1:  360;		方法2:  180;		原位翻转:  397
垂直翻转耗时:方法1:  411;		方法2:  174;		原位翻转:  440

矩阵大小: 142行*142列
水平翻转耗时:方法1:  357;		方法2:  176;		原位翻转:  406
垂直翻转耗时:方法1:  413;		方法2:  173;		原位翻转:  456

矩阵大小: 175行*175列
水平翻转耗时:方法1:  353;		方法2:  173;		原位翻转:  403
垂直翻转耗时:方法1:  412;		方法2:  171;		原位翻转:  452

矩阵大小: 208行*208列
水平翻转耗时:方法1:  359;		方法2:  176;		原位翻转:  408
垂直翻转耗时:方法1:  417;		方法2:  173;		原位翻转:  455

矩阵大小: 241行*241列
水平翻转耗时:方法1:  349;		方法2:  171;		原位翻转:  400
垂直翻转耗时:方法1:  411;		方法2:  170;		原位翻转:  449

矩阵大小: 274行*274列
水平翻转耗时:方法1:  346;		方法2:  173;		原位翻转:  400
垂直翻转耗时:方法1:  406;		方法2:  167;		原位翻转:  448

矩阵大小: 307行*307列
水平翻转耗时:方法1:  343;		方法2:  170;		原位翻转:  400
垂直翻转耗时:方法1:  402;		方法2:  168;		原位翻转:  443

矩阵大小: 340行*340列
水平翻转耗时:方法1:  360;		方法2:  174;		原位翻转:  420
垂直翻转耗时:方法1:  410;		方法2:  169;		原位翻转:  447

矩阵大小: 373行*373列
水平翻转耗时:方法1:  460;		方法2:  259;		原位翻转:  398
垂直翻转耗时:方法1:  512;		方法2:  261;		原位翻转:  443

矩阵大小: 406行*406列
水平翻转耗时:方法1:  456;		方法2:  262;		原位翻转:  403
垂直翻转耗时:方法1:  516;		方法2:  255;		原位翻转:  452

矩阵大小: 439行*439列
水平翻转耗时:方法1:  450;		方法2:  248;		原位翻转:  401
垂直翻转耗时:方法1:  500;		方法2:  249;		原位翻转:  445

矩阵大小: 472行*472列
水平翻转耗时:方法1:  453;		方法2:  269;		原位翻转:  402
垂直翻转耗时:方法1:  513;		方法2:  265;		原位翻转:  450

矩阵大小: 505行*505列
水平翻转耗时:方法1:  433;		方法2:  252;		原位翻转:  390
垂直翻转耗时:方法1:  489;		方法2:  249;		原位翻转:  436

矩阵大小: 538行*538列
水平翻转耗时:方法1:  440;		方法2:  247;		原位翻转:  398
垂直翻转耗时:方法1:  497;		方法2:  247;		原位翻转:  444

矩阵大小: 571行*571列
水平翻转耗时:方法1:  443;		方法2:  256;		原位翻转:  397
垂直翻转耗时:方法1:  496;		方法2:  248;		原位翻转:  440

矩阵大小: 604行*604列
水平翻转耗时:方法1:  439;		方法2:  252;		原位翻转:  402
垂直翻转耗时:方法1:  494;		方法2:  248;		原位翻转:  438

矩阵大小: 637行*637列
水平翻转耗时:方法1:  436;		方法2:  244;		原位翻转:  397
垂直翻转耗时:方法1:  488;		方法2:  242;		原位翻转:  432

矩阵大小: 670行*670列
水平翻转耗时:方法1:  427;		方法2:  243;		原位翻转:  384
垂直翻转耗时:方法1:  483;		方法2:  238;		原位翻转:  427

矩阵大小: 703行*703列
水平翻转耗时:方法1:  449;		方法2:  257;		原位翻转:  403
垂直翻转耗时:方法1:  527;		方法2:  260;		原位翻转:  459

矩阵大小: 736行*736列
水平翻转耗时:方法1:  432;		方法2:  246;		原位翻转:  395
垂直翻转耗时:方法1:  493;		方法2:  245;		原位翻转:  440

矩阵大小: 769行*769列
水平翻转耗时:方法1:  452;		方法2:  258;		原位翻转:  409
垂直翻转耗时:方法1:  518;		方法2:  256;		原位翻转:  458

矩阵大小: 802行*802列
水平翻转耗时:方法1:  434;		方法2:  248;		原位翻转:  392
垂直翻转耗时:方法1:  492;		方法2:  248;		原位翻转:  433

矩阵大小: 835行*835列
水平翻转耗时:方法1:  415;		方法2:  240;		原位翻转:  372
垂直翻转耗时:方法1:  466;		方法2:  234;		原位翻转:  416

矩阵大小: 868行*868列
水平翻转耗时:方法1:  427;		方法2:  247;		原位翻转:  388
垂直翻转耗时:方法1:  478;		方法2:  239;		原位翻转:  433

矩阵大小: 901行*901列
水平翻转耗时:方法1:  448;		方法2:  262;		原位翻转:  400
垂直翻转耗时:方法1:  499;		方法2:  251;		原位翻转:  449

矩阵大小: 934行*934列
水平翻转耗时:方法1:  422;		方法2:  248;		原位翻转:  380
垂直翻转耗时:方法1:  477;		方法2:  237;		原位翻转:  426

矩阵大小: 967行*967列
水平翻转耗时:方法1:  436;		方法2:  257;		原位翻转:  388
垂直翻转耗时:方法1:  493;		方法2:  248;		原位翻转:  438
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics