代码改变世界

你知道for(;;) vs. while(true)那个更快吗?

2019-12-26 12:58  兔子托尼啊  阅读(598)  评论(0编辑  收藏

来来来, 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+年,经历过大大小小公司的洗礼。定期分享技术的文章,希望各位同僚关注我,我们一起探讨技术人生!