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

聊聊React源碼中的位運(yùn)算技巧

開發(fā) 前端
在涉及狀態(tài)、標(biāo)記位、優(yōu)先級操作的地方大量使用了位運(yùn)算。本文會講解其中比較有代表性的部分。學(xué)到之后,當(dāng)遇到類似場景時(shí)露一手,你就是業(yè)務(wù)線最靚的仔。

[[428027]]

大家好,我卡頌。

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

  • 調(diào)度器為什么用小頂堆這種數(shù)據(jù)結(jié)構(gòu),直接用數(shù)組不行?
  • 源碼里各種單向鏈表、環(huán)狀鏈表,直接用數(shù)組不行?
  • 源碼里各種位運(yùn)算,有必要么?

作為業(yè)務(wù)依賴的框架,為了提升一點(diǎn)點(diǎn)運(yùn)行時(shí)性能,React從不吝惜將源碼寫的很復(fù)雜。

[[428028]]

在涉及狀態(tài)、標(biāo)記位、優(yōu)先級操作的地方大量使用了位運(yùn)算。

本文會講解其中比較有代表性的部分。學(xué)到之后,當(dāng)遇到類似場景時(shí)露一手,你就是業(yè)務(wù)線最靚的仔。

幾個(gè)常用位運(yùn)算

在JS中,位運(yùn)算的操作數(shù)會先轉(zhuǎn)換為Int32(32位有符號整型),執(zhí)行完位運(yùn)算會Int32對應(yīng)浮點(diǎn)數(shù)。

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

按位與(&)

對于兩個(gè)二進(jìn)制操作數(shù)的每個(gè)bit,如果都為1,則結(jié)果為1,否則為0。

舉個(gè)例子,計(jì)算3 & 2,首先將操作數(shù)轉(zhuǎn)化為Int32:

  1. // 3對應(yīng)的 Int32 
  2. 0b000 0000 0000 0000 0000 0000 0000 0011  
  3. // 2對應(yīng)的 Int32 
  4. 0b000 0000 0000 0000 0000 0000 0000 0010  

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

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

所以3 & 2計(jì)算結(jié)果轉(zhuǎn)化為浮點(diǎn)數(shù)后為2。

按位或(|)

對于兩個(gè)二進(jìn)制操作數(shù)的每個(gè)bit,如果都為0,則結(jié)果為0,否則為1。

計(jì)算10 | 3:

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

計(jì)算結(jié)果轉(zhuǎn)化為浮點(diǎn)數(shù)后為11。

按位非(~)

對一個(gè)二進(jìn)制操作數(shù)的每個(gè)bit,逐位進(jìn)行取反操作(0、1互換)

對于~3,將3轉(zhuǎn)化為Int32后逐位取反:

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

計(jì)算結(jié)果轉(zhuǎn)化為浮點(diǎn)數(shù)后為-4。

如果你對這個(gè)結(jié)果有疑惑,可以去了解補(bǔ)碼相關(guān)知識

讓我們從易到難,看看位運(yùn)算在React中的應(yīng)用。

標(biāo)記狀態(tài)

React源碼內(nèi)部有多個(gè)上下文環(huán)境,在執(zhí)行函數(shù)時(shí)經(jīng)常需要判斷當(dāng)前處在哪個(gè)上下文環(huán)境中。

假設(shè)共有三種上下文情況:

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

當(dāng)進(jìn)入某個(gè)上下文時(shí),可以使用按位或操作標(biāo)記進(jìn)入:

  1. // 當(dāng)前所處上下文 
  2. let curContext = 0; 
  3.  
  4. // 進(jìn)入A上下文 
  5. curContext |= A; 

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

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

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

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

離開某上下文后,結(jié)合按位與、按位非移除標(biāo)記:

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

curContext與~A執(zhí)行按位與操作:

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

即從curContext中移除A。

當(dāng)業(yè)務(wù)中需要同時(shí)處理多個(gè)狀態(tài)時(shí),可以使用如上位運(yùn)算技巧。

優(yōu)先級計(jì)算

在React中,不同情況下調(diào)用this.setState觸發(fā)的更新會擁有不同優(yōu)先級。優(yōu)先級之間的比較、挑選同樣使用了位運(yùn)算。

具體來說,React中用31個(gè)bit位保存「更新」(之所以是31而不是32是因?yàn)镮nt32的最高位是符號位,不保存具體的數(shù))。

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

舉個(gè)例子,假設(shè)當(dāng)前應(yīng)用存在2個(gè)更新:

  1. 0b000 0000 0000 0000 0000 0000 0001 0001 

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

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

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

解釋下,由于Int32采用「補(bǔ)碼」表示,所以-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 

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

總結(jié)

雖然業(yè)務(wù)中不常使用位操作,但在特定場景下位操作時(shí)很方便、高效的方式。

這波操作你愛了么?

 

責(zé)任編輯:姜華 來源: 魔術(shù)師卡頌
相關(guān)推薦

2023-04-26 07:46:22

React隱藏彩蛋

2020-10-27 07:51:12

Shell腳本日期

2022-04-14 11:50:39

函數(shù)組件hook

2024-01-26 08:06:43

2021-01-23 12:22:59

位運(yùn)算編程語言開發(fā)

2022-03-31 17:54:29

ReactHooks前端

2021-02-21 06:36:57

運(yùn)算技巧按位

2022-05-18 16:06:15

位運(yùn)算異或運(yùn)算

2023-04-07 08:02:54

源碼位邏輯運(yùn)算符

2017-03-06 20:39:41

整潔代碼Clean Code

2014-08-14 10:12:45

SwiftNil Coalesc

2020-10-21 08:38:47

React源碼

2022-09-07 00:04:37

JavaScript運(yùn)算符技巧

2020-11-20 07:51:02

JavaSPI機(jī)制

2021-11-10 18:52:42

SQL技巧優(yōu)化

2022-04-07 12:13:22

技巧高可用單機(jī)版

2022-03-11 19:54:07

Svelte應(yīng)用程序JavaScript

2022-03-29 07:52:21

運(yùn)用技巧二分查找

2021-06-08 06:13:16

React開發(fā)開發(fā)技術(shù)

2022-03-11 10:23:02

React性能優(yōu)化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 午夜免费观看网站 | 国产精品精品视频 | 久久久美女 | 久久久精品久 | 欧美网站一区 | 中文字幕在线观看视频一区 | 国产精品亚洲一区二区三区在线 | 在线中文字幕亚洲 | 国产999精品久久久 午夜天堂精品久久久久 | 欧美午夜精品 | 久久综合九九 | 久久99久久| 成人一区二 | 国产精品久久久久久久一区探花 | 欧美日韩国产精品激情在线播放 | 中文字幕亚洲精品 | 亚洲人精品 | 国产精品久久久久久久久久不蜜臀 | 国产成人高清视频 | 视频一区二区三区四区五区 | 日韩精品一区二区三区视频播放 | 日韩在线xx| 国产精品免费一区二区三区四区 | 国产成人一区二区 | 搞av.com| 精品综合网 | 久久天天躁狠狠躁夜夜躁2014 | 激情网站 | 在线日韩欧美 | www.狠狠干| 一区二区三区视频免费看 | 欧美成年人 | 一区观看| www.国产视频 | 中文字幕在线免费 | 日日干夜夜操 | 99国产精品久久久 | 97精品超碰一区二区三区 | 欧美一级久久 | 日韩精品一区二区三区视频播放 | 国产免费视频在线 |