您希望自己爆肝寫的程式碼不被別人盜取嗎?用goto就對了。
goto就像是任意門,可以自由自在的穿梭到任何地方,用了它,程式碼就會變的亂七八糟的,再也不怕別人盜取自己的程式碼了,goto是最強的跳躍語法,一生無悔控goto,一起用goto來保護自己的程式碼吧~
goto語法教學網
[轉貼]goto的效能比for和while快?
[不專業研究]for、while、goto效能評比
本文轉貼自友站 可雷塔的計算機科學研究所
我們常常聽說goto是一把雙面刃,它可以在程式碼中像任意門一樣穿梭自如,但是卻破壞了程式碼的結構與可讀性。
但是,goto的優點只有跳躍而已嗎?
本文將設計針對for、while、goto的效能做比較的實驗,探討goto是否能對程式碼的效能進行優化。
測試環境:
程式語言:C++
作業系統:Windows7
CPU:Intel i5-3470
使用IDE及編譯器:Visual Studio 2019
平台模式:64位元,debug模式(無最佳化)
以下是實驗程式碼:
我們常常聽說goto是一把雙面刃,它可以在程式碼中像任意門一樣穿梭自如,但是卻破壞了程式碼的結構與可讀性。
但是,goto的優點只有跳躍而已嗎?
本文將設計針對for、while、goto的效能做比較的實驗,探討goto是否能對程式碼的效能進行優化。
測試環境:
程式語言:C++
作業系統:Windows7
CPU:Intel i5-3470
使用IDE及編譯器:Visual Studio 2019
平台模式:64位元,debug模式(無最佳化)
以下是實驗程式碼:
unsigned
int length = 1024 *
1024 * 1024 * 10;
int
length2 = 1024 * 1024 * 1024;
int
key = 0;
std::cout <<
"一層迴圈\n"
;
i = 0;
clock.restart();
for
(i = 0;i < length;i++)
{
key = i;
}
std::cout <<
"for的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
i = 0;
clock.restart();
while
(i < length)
{
key = i;
i++;
}
std::cout <<
"while的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
i = 0;
clock.restart();
flag0:
key = i;
i++;
if
(i < length) goto
flag0;
std::cout <<
"goto的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
std::cout <<
"二層迴圈\n"
;
i = 0;
j = 0;
clock.restart();
for
(j = 0;j < 10;j++) {
for
(i = 0;i < length2;i++)
{
key
= i;
}
}
std::cout <<
"for的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
j = 0;
i = 0;
clock.restart();
while
(j < 10) {
i = 0;
while
(i < length2)
{
key
= i;
i++;
}
j++;
}
std::cout <<
"while的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
i = 0;
j = 0;
clock.restart();
flag:
i = 0;
flag2:
key = i;
i++;
if
(i < length2) goto
flag2;
j++;
if
(j < 10) goto
flag;
std::cout <<
"goto的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
我們分別利用單層迴圈和雙層迴圈測試for、while、goto的效能。
首先,定義了一個 unsigned int的變數length,大小為1024 * 1024 * 1024 * 10。
然後分別設計for、while、goto的單層迴圈去運行它,次數為length。
然後,定義了一個 int的變數length2,大小為1024 * 1024 * 1024。
然後分別設計for、while、goto的雙層迴圈去運行它,次數為10*length2。
所以,單層迴圈和雙層迴圈運轉的次數是一樣的。
最後,我們在迴圈中加入了key=i,模擬實際迴圈中常見的狀況。
測試結果:
在一層迴圈中,for的效能最差,花費時間為4627毫秒,次之則為while,為4426毫秒,令人驚訝的是,goto的效能竟然最高,僅花費了4402毫秒。
然而,進入第二階段的雙層迴圈試驗,原本趨於劣勢的for迴圈竟逆轉局勢並驚險的勝出,花費了22026毫秒,而goto在這場比賽則敬陪末座,總花費時間為22119毫秒。
但是,真的只差了一點點,我們再重跑一次程式:
在第二次,在一層迴圈中,一樣是由goto勝出,但是呢,在雙層迴圈中,goto再次贏過for和while拿下勝利,總花費時間為22018毫秒,while則敬陪末座。
可見在第二層迴圈中,三者的速度是差不多的。
但是,如何讓goto在雙層迴圈中發揮它在單層迴圈的優勢呢?
我們再做個實驗
unsigned
int length = 1024 *
1024 * 1024 * 10;
int
length2 = 1024 * 1024 * 1024;
int
key = 0;
i = 0;
j = 0;
clock.restart();
for
(j = 0;j < 10;j++) {
for
(i = 0;i < length2;i++)
{
key
= i;
}
}
std::cout <<
"for+for的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
i = 0;
j = 0;
clock.restart();
for
(j = 0;j < 10;j++)
{
i = 0;
flag1:
i++;
key = i;
if
(i < length2)goto
flag1;
}
std::cout <<
"for+goto的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
i = 0;
j = 0;
clock.restart();
flag3:
i = 0;
for
(i = 0;i < length2;i++)
{
key = i;
}
j++;
if
(j < 10) goto
flag3;
std::cout <<
"goto+for的時間為"
<< clock.GetTime() <<
"毫秒\n"
;
在這一次,我們分別使用雙層for迴圈、外圈為for內圈為goto、外圈為goto內圈為for,來做測試,跑的次數跟上一次的實驗一樣。
測試結果:
果不其然,讓goto在內層迴圈,效能上會有顯著優勢,而放在外層則不具有優勢。
為了防止運氣問題,我們再讓程式跑一次:
一樣的,for+goto再度以19074毫秒壓倒性的勝出,for+for最差,為22196毫秒,goto+for則為22123毫秒
結論:
在單層迴圈中,goto在效能上會比for和while來的有優勢,而在雙層迴圈中,goto在內層迴圈中依然可以為效能帶來貢獻。
這次的for、while、goto不專業效能評比就到這邊結束了,如果有其他點子想測試的,歡迎留言一起來做討論,我們下次見囉!
利用goto,算出最小公倍數
int number1=255, number2=800,number3=0,product=0; int temporarily = Math.Max(number1, number2); number2 = Math.Min(number1, number2); number1 = temporarily; product = number1 * number2; while1: number1 = number1 > number2 ? number1 : number2; number3 = number1 % number2; number1 = number2; number2 = number3; if (number2 != 0) goto while1; Console.Write(product/number1);
利用goto,算出最大公因數
int number1=54, number2=24,number3=0; int temporarily = Math.Max(number1, number2); number2 = Math.Min(number1, number2); number1 = temporarily; while1: number1 = number1 > number2 ? number1 : number2; number3 = number1 % number2; number1 = number2; number2 = number3; if (number2 != 0) goto while1; Console.Write(number1);
利用goto,進行氣泡排序
int[] list = new int[9] { 2, 4, 6, 7, 1, 9, 3, 8, 5 }; int temporarily; Boolean flag = true ; int i=1; int j=1; for1: flag =false ; j = 1; for2: if (list[j] < list[j - 1]) { temporarily = list[j]; list[j] = list[j - 1]; list[j - 1] = temporarily; flag = true ; } if (j<9-i) { j += 1; goto for2; } if (i < 8 && flag == true ) { i += 1; goto for1; } j = 0; for3: Console.Write(list[j] + " "); j++; if (j < 9) goto for3;
利用goto,印出九九乘法表
int X = 1; int Y = 1; for1: Y = 1; for2: Y+= 1; if (Y* X <= 9) Console.Write(Y + "X" + X + "=0" + Y * X + " "); else Console.Write(Y + "X" + X + "=" + Y * X + " "); if (Y <= 8) goto for2; X += 1; Console.WriteLine(); if (X <= 9) goto for1;
利用goto,印出倒三角形
int triangle1 = 0; int triangle2 = 9; for1: triangle2 = 9; for2: triangle2 -= 1; Console.Write(0); if (triangle2 > triangle1) goto for2; triangle1 += 1; Console.WriteLine(); if (triangle1 < 9) goto for1;
訂閱:
文章 (Atom)