你知道for(;;) vs. while(true)那個更快嗎?


來來來, for(;😉 vs. while(true) 有什么區別?從java的語義上來說,他們是一模一樣的。為何怎么說?

開始我們先測試for(;😉

package com.tony.test;
import org.junit.Test;
/**
 * 測試循環
 *
 * @author tony
 * @create 2019-12-26 10:43
 **/
public class LoopTest {
    @Test
    public void testFor() {
        for (; ; ) {
            System.out.println("Tony Teacher test for");
        }
    }
}

輸出的字節碼如下

// class version 51.0 (51)
// access flags 0x21
public class com/tony/test/LoopTest {
  // compiled from: LoopTest.java
  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 11 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/tony/test/LoopTest; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public testFor()V
  @Lorg/junit/Test;()
   L0
    LINENUMBER 16 L0
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "Tony Teacher test for"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    GOTO L0
   L1
    LOCALVARIABLE this Lcom/tony/test/LoopTest; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

我們再測試while (true)

package com.tony.test;
import org.junit.Test;
/**
 * 測試循環
 *
 * @author tony
 * @create 2019-12-26 10:43
 **/
public class LoopTest {
    @Test
    public void testWhile() {
        while (true) {
            System.out.println("Tony Teacher test while");
        }
    }
}

輸出的字節碼如下

// class version 51.0 (51)
// access flags 0x21
public class com/tony/test/LoopTest {
  // compiled from: LoopTest.java
  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 11 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/tony/test/LoopTest; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public testFor()V
  @Lorg/junit/Test;()
   L0
    LINENUMBER 16 L0
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "Tony Teacher test while"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    GOTO L0
   L1
    LOCALVARIABLE this Lcom/tony/test/LoopTest; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

引用網上的一段話

Semantically, they're completely equivalent. It's a matter of taste, but I think while(true) looks cleaner, and is easier to read and understand at first glance. In Java neither of them causes compiler warnings.
At the bytecode level, it might depend on the compiler and the level of optimizations, but in principle the code emitted should be the same.

這個兩種寫法都是可以的,取決於編譯器和優化的級別,原則上是一模一樣的。

下次面試官再問你這種問題,你就可以懟回去。通過ASM,查看byteCode碼。這兩貨是一模一樣的。對我而言,我喜歡用for(;;),感覺for里面肯定會有退出循環的情況,

但是while(true),咋一看會感覺一直會循環下去。
只是看個人喜歡,你喜歡用那種寫法呢?

再講講 while(true)

當你使用一個空循環的時候,你觀察一下不一會你的CPU使用率就達到100%,如何不讓CPU使用達到100%?此刻如果面試官問你,你該怎么回答?
Thread.sleep , 對的sleep方法。因為while 會消耗掉所有可以的計算資源。你此刻如果生成dump文件,你會發現jvm垃圾回收時間是很頻繁的。

while (true)
{
    try
    {
        Thread.sleep(500);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

500毫秒毫秒循環一次,你可別小看這500毫秒。你可知道一毫秒cpu可以做很多的事情了。此刻你線程等待,可以讓cpu去干其他的事情了。

你猜對了答案嗎?其實這些問題,我們平常看源碼都看到過。但是你有沒有去總結為什么這么寫?知其然更知其所以然。IT這條路是漫長、孤獨且枯燥,需要靜下心來好好琢磨學習。堅持下來,你一定會享受到編碼帶來的快樂和財富。

掃一掃關注下,更多分享等着你。

『托尼老師』從事互聯網研發工作10+年,經歷過大大小小公司的洗禮。定期分享技術的文章,希望各位同僚關注我,我們一起探討技術人生!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM