成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官又整新活,居然問我 For 循環用 i++ 和 ++i 哪個效率高?

開發 前端
聽到這,我感覺這面試官確實有點不按套路出牌了,放著好好的八股文不問,凈整些幺蛾子的東西。在臨走的時候,小伙伴問面試官這道題的答案是什么,面試官沒有明確告訴答案,只是說讓從程序執行的效率角度自己思考一下。

前幾天,一個小伙伴告訴我,他在面試的時候被面試官問了這么一個問題:

在for循環中,到底應該用 i++ 還是 ++i ?

聽到這,我感覺這面試官確實有點不按套路出牌了,放著好好的八股文不問,凈整些幺蛾子的東西。在臨走的時候,小伙伴問面試官這道題的答案是什么,面試官沒有明確告訴答案,只是說讓從程序執行的效率角度自己思考一下。

好吧,既然這個問題被拋了出來,那我們就見招拆招,也給以后面試的小伙伴們排一下坑。

思路

前面提到,這個搞事情的面試官說要從執行效率的角度思考,那我們就拋開語義上的區別,從運行結果以外的效率來找找線索?;叵胍幌?,我們在以前介紹CAS的文章中提到過,后置自增i++和前置自增++i都不是原子操作,那么實際在執行過程中是什么樣的呢?下面,我們從字節碼指令的角度,從底層進行一波分析。

i++ 執行過程

先寫一段簡單的代碼,核心功能就只有賦值和自增操作:

  1. public static void main(String[] args) { 
  2.     int i=3; 
  3.     int j=i++; 
  4.     System.out.println(j); 

下面用javap對字節碼文件進行反編譯,看一下實際執行的字節碼指令:

是不是有點難懂?沒關系,接下來我們用圖解的形式來直觀地看看具體執行的過程,也幫大家解釋一下晦澀的字節碼指令是如何操作棧幀中的數據結構的,為了簡潔起見,在圖中只列出棧幀中比較重要的操作數棧和局部變量表。

上面的代碼中除去打印語句,整體可以拆分成兩步,我們先看第一步 int i=3 是如何執行的 。

上面兩條操作數棧和局部變量表相關的字節碼指令還是比較容易理解的,下面再看一下第二步int j=i++的執行過程:

在上圖中需要注意的是,iinc能夠直接更新局部變量表中的變量值,它不需要把數值壓到操作數棧中就能夠直接進行操作。在上面的過程中,拋去賦值等其他操作,i++實際執行的字節碼指令是:

  1. 2: iload_1 
  2.  
  3. 3: iinc 1, 1 

如果把它翻譯成我們能看懂的java代碼,可以理解為:

  1. int temp=i; 
  2.  
  3. i=i+1; 

也就是說在這個過程中,除了必須的自增操作以外,又引入了一個新的局部變量,接下來我們再看看++i的執行過程。

++i 執行過程

我們對上面的代碼做一點小小的改動,僅把i++換成++i,再來分析一下++i的執行過程是怎樣的。

  1. public static void main(String[] args) { 
  2.  
  3. int i=3; 
  4.  
  5. int j=++i; 
  6.  
  7. System.out.println(j); 
  8.  

同樣,用javap反編譯字節碼文件:

int i=3對應前兩行字節碼指令,執行過程和前面i++例子中完全相同,可以忽略不計,重點還是通過圖解的方式看一下int j=++i對應的字節碼指令的執行過程:

拋去賦值操作,++i實際執行過程只有一行字節碼指令:

  1. 2: iinc 1, 1 

轉換成能理解的java代碼的話,++i實際執行的就在局部變量中執行的:

  1. i=i+1; 

這么看來,在使用++i時確實比i++少了一步操作,少引入了一個局部變量,如果在運算結果相同的場景下,使用++i的話的確效率會比i++高那么一點點。

那么回到開頭的問題,兩種自增方式應用在for循環中執行的時候,那種效率更高呢?剛才得出的結論仍然適用于for循環中嗎,別急,讓我們接著往下看。

for循環中的自增

下面準備兩段包含了for循環的代碼,分別使用i++后置自增和++i前置自增:

  1. //i++ 后置自增 
  2. public class ForIpp { 
  3.     public static void main(String[] args) { 
  4.         for (int i = 0; i < 5; i++) { 
  5.             System.out.println(i); 
  6.         } 
  7.     } 
  8. //++i 前置自增 
  9. public class ForPpi { 
  10.     public static void main(String[] args) { 
  11.         for (int i = 0; i < 5; ++i) { 
  12.             System.out.println(i); 
  13.         } 
  14.     } 

老規矩,還是直接反編譯后的字節碼文件,然后對比一下指令的執行過程:

到這里,有趣的現象出現了,兩段程序執行的字節碼指令部分居然一模一樣。先不考慮為什么會有這種現象,我們還是通過圖解來看一下字節碼指令的執行過程:

可以清晰的看到,在進行自增時,都是直接執行的iinc,在之前并沒有執行iload的過程,也就是說,兩段代碼執行的都是++i。這一過程的驗證其實還有更簡單的方法,直接使用idea打開字節碼文件,就可以看到最終for循環中使用的相同的前置自增方式。

那么,為什么會出現這種現象呢?歸根結底,還是java編譯器對于代碼的優化,在兩種自增方式中,如果沒有賦值操作,那么都會被優化成一種方式,就像下面的兩個方法的代碼:

  1. void ipp(){ 
  2.     int i=3; 
  3.     i++; 
  4. void ppi(){ 
  5.     int i=3; 
  6.     ++i; 

最終執行時的字節碼指令都是:

  1. 0: iconst_3 
  2.  
  3. 1: istore_1 
  4.  
  5. 2: iinc 1, 1 
  6.  
  7. 5: return 

可以看到,在上面的這種特定情況下,代碼經過編譯器的優化,保持了語義不變,并通過轉換語法的形式提高了代碼的運行效率。所以再回到我們開頭的問題,就可以得出結論,在for循環中,通過jvm進行編譯優化后,不論是i++還是++i,最終執行的方式都是++i,因此執行效率是相同的。

所以,以后再碰到這種半吊子的面試官,和你談for循環中i++和++i的效率問題,自信點,直接把答案甩在他的臉上,兩種方式效率一樣! 

本文代碼基于Java 1.8.0_261-b12 版本測試

 

責任編輯:武曉燕 來源: 碼農參上
相關推薦

2022-03-31 16:47:30

mysqlcount面試官

2019-09-11 09:09:56

++ii++編程語言

2022-11-25 17:29:27

分布式事務

2021-12-02 08:19:06

MVCC面試數據庫

2024-04-08 10:35:59

JS代碼容量

2020-04-16 08:22:11

HTTPS加解密協議

2021-05-20 08:54:16

Go面向對象

2010-08-23 15:06:52

發問

2022-05-24 08:03:28

InnoDBMySQL數據

2023-09-28 08:21:20

i++++i高并發

2021-08-02 09:31:20

Python工具代碼

2020-10-26 07:07:50

線程安全框架

2021-06-03 08:55:54

分布式事務ACID

2022-10-17 00:04:30

索引SQL訂單

2020-12-03 07:39:50

HashMap底層數據

2024-01-31 23:47:17

i++++i編碼

2023-01-03 18:06:42

高并發架構

2024-02-28 10:14:47

Redis數據硬盤

2020-08-10 07:58:18

異步編程調用

2021-05-08 07:53:33

面試線程池系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91久久久久久| 久久久久久久一区二区三区 | 在线视频日韩 | 国产成人高清在线观看 | av一区二区三区四区 | 国产精品成人在线观看 | 一区二区三区电影在线观看 | 国产成人精品久久 | 欧美激情视频一区二区三区在线播放 | 黑人巨大精品欧美一区二区免费 | 久久免费国产 | 欧美一级视频免费看 | 久久蜜桃av | 日本天天操 | 国产日韩欧美二区 | 国产日韩欧美综合 | 日韩精品一区二区三区视频播放 | 成人av免费在线观看 | 久久国产精品一区二区三区 | 国产精品高潮呻吟久久 | 亚洲欧美激情精品一区二区 | 亚洲狠狠 | 水蜜桃久久夜色精品一区 | 伊人久久在线观看 | 嫩草国产| 国产精品一区二区在线播放 | 久久久久久一区 | 国产午夜在线 | 免费观看av网站 | 成人网在线看 | 国产精品久久国产精品99 | av一级| av免费网址 | av日韩在线播放 | 精品国产精品三级精品av网址 | 久久激情视频 | 日韩成人一区 | 婷婷久久久久 | 国产精品免费一区二区三区四区 | hitomi一区二区三区精品 | 久久av网|