[英]Java for loop vs. while loop. Performance difference?
假設我有以下代碼,有三個 for 循環來做某事。 如果我將最外層的 for 循環更改為 while 循環,它會運行得很快嗎? 謝謝~~
int length = 200;
int test = 0;
int[] input = new int[10];
for(int i = 1; i <= length; i++) {
for (int j = 0; j <=length - i; j++) {
for (int k = 0; k < length - 1; k++) {
test = test + input[j + k];
}
}
}
不,更改循環類型無關緊要。
唯一可以使它更快的方法是減少嵌套循環,並循環使用更少的值。
for
循環和while
循環之間的唯一區別是定義它們的語法。 根本沒有性能差異。
int i = 0;
while (i < 20){
// do stuff
i++;
}
是相同的:
for (int i = 0; i < 20; i++){
// do Stuff
}
(實際上 for 循環要好一些,因為循環后i
將超出范圍,而i
將留在while
循環中。)
for 循環只是一種語法上更漂亮的循環方式。
這種微優化毫無意義。
有人建議測試while
與for
循環,所以我創建了一些代碼來測試 while 循環或 for 循環是否更快; 平均而言,超過 100,000 次測試, while
循環在大約 95% 的時間內更快。 我可能編碼不正確,我對編碼很陌生,還考慮到如果我只運行了 10,000 次循環,它們最終的運行持續時間相當均勻。
編輯當我去測試更多試驗時,我沒有改變所有的數組值。 修復了它,以便更輕松地更改您運行的試驗次數。
import java.util.Arrays;
class WhilevsForLoops {
public static void main(String[] args) {
final int trials = 100; //change number of trials
final int trialsrun = trials - 1;
boolean[] fscount = new boolean[trials]; //faster / slower boolean
int p = 0; // while counter variable for for/while timers
while (p <= trialsrun) {
long[] forloop = new long[trials];
long[] whileloop = new long[trials];
long systimeaverage;
long systimenow = System.nanoTime();
long systimethen = System.nanoTime();
System.out.println("For loop time array : ");
for (int counter=0;counter <= trialsrun; counter++) {
systimenow = System.nanoTime();
System.out.print(" #" + counter + " @");
systimethen = System.nanoTime();
systimeaverage = (systimethen - systimenow);
System.out.print( systimeaverage + "ns |");
forloop[counter] = systimeaverage;
}
int count = 0;
System.out.println(" ");
System.out.println("While loop time array: ");
while (count <= trialsrun) {
systimenow = System.nanoTime();
System.out.print(" #" + count + " @");
systimethen = System.nanoTime();
systimeaverage = (systimethen - systimenow);
System.out.print( systimeaverage + "ns |");
whileloop[count] = systimeaverage;
count++;
}
System.out.println("===============================================");
int sum = 0;
for (int i = 0; i <= trialsrun; i++) {
sum += forloop[i];
}
System.out.println("for loop time average: " + (sum / trials) + "ns");
int sum1 = 0;
for (int i = 0; i <= trialsrun; i++) {
sum1 += whileloop[i];
}
System.out.println("while loop time average: " + (sum1 / trials) + "ns");
int longer = 0;
int shorter = 0;
int gap = 0;
sum = sum / trials;
sum1 = sum1 / trials;
if (sum1 > sum) {
longer = sum1;
shorter = sum;
}
else {
longer = sum;
shorter = sum1;
}
String longa;
if (sum1 > sum) {
longa = "~while loop~";
}
else {
longa = "~for loop~";
}
gap = longer - shorter;
System.out.println("The " + longa + " is the slower loop by: " + gap + "ns");
if (sum1 > sum) {
fscount[p] = true; }
else {
fscount[p] = false;
}
p++;
}
int forloopfc=0;
int whileloopfc=0;
System.out.println(Arrays.toString(fscount));
for(int k=0; k <= trialsrun; k++) {
if (fscount[k] == true) {
forloopfc++; }
else {
whileloopfc++;}
}
System.out.println("--------------------------------------------------");
System.out.println("The FOR loop was faster: " + forloopfc + " times.");
System.out.println("The WHILE loop was faster: " + whileloopfc + " times.");
}
}
您無法通過將其更改為 while 來優化它。
你可以通過改變線路來非常非常非常非常小地增加速度
for (int k = 0; k < length - 1; k++) {
經過
for (int k = 0; k < lengthMinusOne; k++) {
其中 lengthMinusOne 之前計算過
這個減法只是計算幾乎 (200x201/2) x (200-1) 次,對於計算機來說是非常少的數字:)
這是一篇關於此事的文章的有用鏈接
根據它,While 和 For 幾乎快兩倍,但兩者都是相同的。
但是這篇文章是在 2009 年寫的,所以我在我的機器上試了一下,結果如下:
所以我想最好的辦法就是在你自己的版本和機器上計時,然后得出結論
即使 while 循環比 for 循環更快的假設是正確的(事實並非如此),您必須更改/優化的循環不會是外部循環而是內部循環,因為這些循環執行的次數更多.
for 和 while 之間的區別在於語義:
這是一種幫助他人理解您的代碼的方式。 您沒有義務不修改 for 循環變量,但這是一種常見(且良好)的做法。
不,您仍然循環完全相同的次數。 根本沒有關系。
看看你的算法! 您是否事先知道數組中的哪些值被添加了多次?
如果您知道可以減少循環次數,從而提高性能。
有沒有人這樣試過...
int i = 20;
while (--i > -1){
// do stuff
}
相比:
for (int i = 0; i < 20; i++){
// do Stuff
}
不會有性能差異。 試試看!
JVM 以及編譯器會將兩個循環都變成類似
label:
;code inside your for loop.
LOOP label
僅當您使用多線程或多處理器編程時才重要。 然后它還取決於您如何將循環分配給各種處理器/線程。
不,這不會有太大的不同,唯一的問題是,如果您可能出於組織目的考慮切換嵌套循環,則可能希望在外部使用 while 循環並在其中使用 for 語句。 這不會影響性能,但只會使您的代碼看起來更清晰/有條理
你可以自己計算。
int length = 200;
int test = 0;
int[] input = new int[10];
long startTime = new Date().getTime();
for(int i = 1; i <= length; i++) {
for (int j = 0; j <=length - i; j++) {
for (int k = 0; k < length - 1; k++) {
test = test + input[j + k];
}
}
}
long endTime = new Date().getTime();
long difference = endTime - startTime;
System.out.println("For - Elapsed time in milliseconds: " + difference);
test = 0;
input = new int[10];
int i = 0, j = 0, k = 0;
startTime = new Date().getTime();
while(i < length) {
while(j <= length - i ) {
while(k < length - 1) {
test = test + input[j + k];
k++;
}
j++;
}
i++;
}
endTime = new Date().getTime();
difference = endTime - startTime;
System.out.println("While - Elapsed time in milliseconds: " + difference);
for
循環和while
循環都是迭代語句,但都有各自不同的特點。
句法
While 循環
//setup counter variable
int counter = 0;
while ( condition) {
//instructions
//update counter variable
counter++; //--> counter = counter + 1;
}
For循環
for (initialization; condition; iteration){
//body of for loop
}
for
循環的所有聲明(初始化、條件、迭代)都在循環體的頂部。 相反,在while
循環中,只有初始化和條件位於循環體的頂部,並且迭代可以寫在循環體的任何位置。
for 和 while 循環之間的主要區別
在for
循環中,初始化、條件檢查以及迭代變量的遞增或遞減僅在循環語法中明確完成。 相反,在While
循環中,我們只能在循環的語法中初始化和檢查條件。
當我們知道循環執行中必須發生的迭代次數時,我們使用 for 循環。 另一方面,如果我們不知道循環中必須發生的迭代次數,那么我們使用while
循環。
如果沒有將條件語句放入for
循環中,則會導致循環無限迭代。 相反,如果在while
循環中沒有放入條件語句,則會導致編譯錯誤。
for
循環語法中的初始化語句僅在循環開始時執行一次。 相反,如果while
循環在其語法中帶有初始化語句,則 while 循環中的初始化語句將在每次循環迭代時執行。
for
循環中的迭代語句將在for
循環體執行后執行。 相反,迭代語句可以寫在while
循環體中的任何位置,因此,在 `while 循環體中可以有一些語句在執行完迭代語句之后執行。
基於此: https : //jsperf.com/loops-analyze (不是我創建的)while 循環通常比 for 循環慢 22%。 至少在 Javascript 中是這樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.