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

聊聊React源碼中的位運算技巧

開發 前端
在涉及狀態、標記位、優先級操作的地方大量使用了位運算。本文會講解其中比較有代表性的部分。學到之后,當遇到類似場景時露一手,你就是業務線最靚的仔。

[[428027]]

大家好,我卡頌。

這兩年有不少朋友和我吐槽React源碼,比如:

  • 調度器為什么用小頂堆這種數據結構,直接用數組不行?
  • 源碼里各種單向鏈表、環狀鏈表,直接用數組不行?
  • 源碼里各種位運算,有必要么?

作為業務依賴的框架,為了提升一點點運行時性能,React從不吝惜將源碼寫的很復雜。

[[428028]]

在涉及狀態、標記位、優先級操作的地方大量使用了位運算。

本文會講解其中比較有代表性的部分。學到之后,當遇到類似場景時露一手,你就是業務線最靚的仔。

幾個常用位運算

在JS中,位運算的操作數會先轉換為Int32(32位有符號整型),執行完位運算會Int32對應浮點數。

在React中,主要用到3種位運算符 —— 按位與、按位或、按位非。

按位與(&)

對于兩個二進制操作數的每個bit,如果都為1,則結果為1,否則為0。

舉個例子,計算3 & 2,首先將操作數轉化為Int32:

  1. // 3對應的 Int32 
  2. 0b000 0000 0000 0000 0000 0000 0000 0011  
  3. // 2對應的 Int32 
  4. 0b000 0000 0000 0000 0000 0000 0000 0010  

為了直觀,我們排除前面的0,只保留最后8位(實際參與計算的應該是32位):

  1.   0000 0011 
  2. & 0000 0010 
  3. ----------- 
  4.   0000 0010 

所以3 & 2計算結果轉化為浮點數后為2。

按位或(|)

對于兩個二進制操作數的每個bit,如果都為0,則結果為0,否則為1。

計算10 | 3:

  1.   0000 1010 
  2. | 0000 0011 
  3. ----------- 
  4.   0000 1011 

計算結果轉化為浮點數后為11。

按位非(~)

對一個二進制操作數的每個bit,逐位進行取反操作(0、1互換)

對于~3,將3轉化為Int32后逐位取反:

  1. // 3對應的 Int32 
  2. 0b000 0000 0000 0000 0000 0000 0000 0011  
  3. // 逐位取反 
  4. 0b111 1111 1111 1111 1111 1111 1111 1100 

計算結果轉化為浮點數后為-4。

如果你對這個結果有疑惑,可以去了解補碼相關知識

讓我們從易到難,看看位運算在React中的應用。

標記狀態

React源碼內部有多個上下文環境,在執行函數時經常需要判斷當前處在哪個上下文環境中。

假設共有三種上下文情況:

  1. // A上下文 
  2. const A = 1; 
  3. // B上下文 
  4. const B = 2; 
  5. // 沒有處在上下文 
  6. const NoContext = 0; 

當進入某個上下文時,可以使用按位或操作標記進入:

  1. // 當前所處上下文 
  2. let curContext = 0; 
  3.  
  4. // 進入A上下文 
  5. curContext |= A; 

我們用8位二進制舉例(同樣,實際應該是Int32,這里是為了簡化),curContext與A執行按位或操作:

  1.   0000 0000  // curContext 
  2. | 0000 0001  // A 
  3. ----------- 
  4.   0000 0001 

此時可以結合按位與操作與NoContext來判斷是否處在某一上下文中:

  1. // 是否處在A上下文中 true 
  2. (curContext & A) !== NoContext 
  3.  
  4. // 是否處在B上下文中 false 
  5. (curContext & B) !== NoContext 

離開某上下文后,結合按位與、按位非移除標記:

  1. // 從當前上下文中移除上下文A 
  2. curContext &= ~A; 
  3.  
  4. // 是否處在A上下文中 false 
  5. (curContext & A) !== NoContext 

curContext與~A執行按位與操作:

  1.   0000 0001  // curContext 
  2. & 1111 1110  // ~A 
  3. ----------- 
  4.   0000 0000 

即從curContext中移除A。

當業務中需要同時處理多個狀態時,可以使用如上位運算技巧。

優先級計算

在React中,不同情況下調用this.setState觸發的更新會擁有不同優先級。優先級之間的比較、挑選同樣使用了位運算。

具體來說,React中用31個bit位保存「更新」(之所以是31而不是32是因為Int32的最高位是符號位,不保存具體的數)。

處在越低bit位的更新優先級越高(越需要優先處理)。

舉個例子,假設當前應用存在2個更新:

  1. 0b000 0000 0000 0000 0000 0000 0001 0001 

其中第1位的更新優先級最高(需要同步處理),第5位為默認優先級。

React經常需要找出當前最高優先級的更新在哪一位(如上例子中在第一位),方法如下:

  1. function getHighestPriorityLane(lanes) { 
  2.   return lanes & -lanes; 

解釋下,由于Int32采用「補碼」表示,所以-lanes可以看作如下兩步操作:

  1. lanes取反(~lanes)
  2. 加1

為了直觀,用8位表示:

  1. lanes  0001 0001 
  2. ~lanes 1110 1110 // 第一步 
  3. +1     1110 1111 // 第二步 

則lanes & -lanes如下:

  1.   0001 0001 // lanes   
  2. & 1110 1111 // -lanes 
  3. ----------- 
  4.   0000 0001 

取到的就是第一位(已有更新中最高的優先級)。

總結

雖然業務中不常使用位操作,但在特定場景下位操作時很方便、高效的方式。

這波操作你愛了么?

 

責任編輯:姜華 來源: 魔術師卡頌
相關推薦

2023-04-26 07:46:22

React隱藏彩蛋

2020-10-27 07:51:12

Shell腳本日期

2022-04-14 11:50:39

函數組件hook

2024-01-26 08:06:43

2022-03-31 17:54:29

ReactHooks前端

2021-01-23 12:22:59

位運算編程語言開發

2022-05-18 16:06:15

位運算異或運算

2017-03-06 20:39:41

整潔代碼Clean Code

2021-02-21 06:36:57

運算技巧按位

2023-04-07 08:02:54

源碼位邏輯運算符

2020-10-21 08:38:47

React源碼

2014-08-14 10:12:45

SwiftNil Coalesc

2022-09-07 00:04:37

JavaScript運算符技巧

2020-11-20 07:51:02

JavaSPI機制

2021-11-10 18:52:42

SQL技巧優化

2022-04-07 12:13:22

技巧高可用單機版

2022-03-11 19:54:07

Svelte應用程序JavaScript

2022-03-29 07:52:21

運用技巧二分查找

2022-03-11 10:23:02

React性能優化

2021-06-08 06:13:16

React開發開發技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一级毛片成人免费看a | 成人在线视频一区 | 永久网站 | 美女黄频| 久久999| 欧美成人a | 久久最新| 亚洲精品乱码久久久久久久久久 | 久久精品国产一区老色匹 | 国产一区精品在线 | 久久亚洲国产精品 | 日韩精品免费视频 | 人成精品 | 一区二区三区视频在线 | 射欧美 | 亚洲综合无码一区二区 | 一久久久 | 国产成人精品999在线观看 | 午夜精品 | 日韩av福利在线观看 | 日韩一区二区三区四区五区六区 | 久久久久一区 | 九九热免费视频在线观看 | 免费国产视频在线观看 | 99精品国产一区二区青青牛奶 | 麻豆久久久久 | 成人久久久 | 久久午夜精品福利一区二区 | 91视视频在线观看入口直接观看 | 欧洲高清转码区一二区 | 亚洲精品国产精品国自产在线 | 91社区在线观看播放 | 天天干精品 | 欧美日韩在线播放 | 男女视频在线观看 | 特黄色一级毛片 | 中文字幕高清在线 | 久久久久久九九九九九九 | 最近中文字幕第一页 | 精产国产伦理一二三区 | 日韩精品四区 |