Let's talk about bitwise operations in React source code in detail

Let's talk about bitwise operations in React source code in detail

Preface

In the past two years, many friends have complained to me about the React source code, such as:

  • Why does the scheduler use a data structure like a mini-heap instead of an array?
  • There are various one-way linked lists and circular linked lists in the source code. Can't we just use arrays?
  • Are various bit operations in the source code necessary?

As a business-dependent framework, React never hesitates to make the source code complex in order to improve runtime performance a little bit.

Bit operations are used extensively where status, flag bits, and priority operations are involved.
This article will explain the more representative parts of them. After learning it, show off your skills when you encounter similar scenarios, and you will be the most impressive person in your business line.

Several common bit operations

In JS, the operands of bit operations will first be converted to Int32 (32-bit signed integer), and after the bit operation is performed, the corresponding floating-point number of Int32 will be converted.

In React, there are three main bitwise operators used - bitwise and, bitwise or, and bitwise not.

Bitwise AND (&)

For each bit of the two binary operands, if both bits are 1, then the result is 1, otherwise it is 0.

For example, to calculate 3 & 2, first convert the operands to Int32:

// Int32 corresponding to 3
0b000 0000 0000 0000 0000 0000 0000 0011 
// Int32 corresponding to 2
0b000 0000 0000 0000 0000 0000 0000 0010 

For the sake of intuitiveness, we exclude the leading 0s and keep only the last 8 bits (the actual number of bits involved in the calculation should be 32 bits):

  0000 0011
& 0000 0010
-----------
  0000 0010

So the result of 3 & 2 converted to a floating point number is 2.

Bitwise OR (|)

For each bit of the two binary operands, if both bits are 0, then the result is 0, otherwise it is 1.

Calculate 10 | 3:

  0000 1010
| 0000 0011
-----------
  0000 1011

The calculation result is converted to a floating point number and is 11.

Bitwise NOT (~)

For each bit of a binary operand, perform a bit-by-bit inversion operation (0 and 1 are swapped)

For ~3, convert 3 to Int32 and then invert each bit:

// Int32 corresponding to 3
0b000 0000 0000 0000 0000 0000 0000 0011 
// Bitwise inversion 0b111 1111 1111 1111 1111 1111 1111 1100

The calculation result converted to a floating point number is -4.

If you are confused about this result, you can learn about the knowledge of complement code.

Let's look at the application of bitwise operations in React from easy to difficult.

Mark Status

There are multiple contexts in the React source code, and when executing a function, it is often necessary to determine which context is currently in.

Assume there are three contexts:

// A context const A = 1;
// B context const B = 2;
// Not in context const NoContext = 0;

When entering a context, you can use the bitwise OR operation to mark the entry:

// Current context let curContext = 0;

// Enter context A curContext |= A;

Let's use 8-bit binary as an example (again, it should actually be Int32, but this is for simplicity), and perform a bitwise OR operation on curContext and A:

  0000 0000 // curContext
| 0000 0001 // A
-----------
  0000 0001

At this point, you can combine the bitwise AND operation with NoContext to determine whether you are in a certain context:

// Is it in context A? true
(curContext & A) !== NoContext

// Is it in context B? false
(curContext & B) !== NoContext

After leaving a context, combine bitwise AND and bitwise NOT to remove the mark:

// Remove context A from the current context
curContext &= ~A;

// Is it in context A? false
(curContext & A) !== NoContext

curContext performs a bitwise AND operation with ~A:

  0000 0001 // curContext
& 1111 1110 // ~A
-----------
  0000 0000

That is, remove A from curContext.

When the business needs to process multiple states at the same time, you can use techniques such as upper-order operations.

Priority calculation

In React, updates triggered by calling this.setState in different situations have different priorities. The comparison and selection between priorities also use bit operations.
Specifically, React uses 31 bits to store updates (the reason why it is 31 instead of 32 is because the highest bit of Int32 is the sign bit and does not store the specific number).

The lower the bit position, the higher the update priority (the more it needs to be processed first).

For example, suppose there are 2 updates in the current application:

0b000 0000 0000 0000 0000 0000 0001 0001

The update priority at No. 1 is the highest (needs to be processed synchronously), and the update priority at No. 5 is the default priority.

React often needs to find out which update is the highest priority (in the first place in the example above), and the method is as follows:

function getHighestPriorityLane(lanes) {
  return lanes & -lanes;
}

To explain, since Int32 uses two's complement representation, -lanes can be seen as the following two-step operation:

  1. Lanes negation (~lanes)
  2. Add 1

For the sake of clarity, we use 8 bits:

lanes 0001 0001
~lanes 1110 1110 // first step + 1 1110 1111 // second step

Then lanes & -lanes are as follows:

  0001 0001 // lanes  
& 1110 1111 // -lanes
-----------
  0000 0001

The one that is taken is the first one (the highest priority among the existing updates).

Summarize

Although bit operations are not often used in business, they are a convenient and efficient method in certain scenarios.

Do you love this operation?

This is the end of this article about the median operation skills in React source code. For more relevant content about median operation skills in React source code, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • In-depth study of setState source code in React
  • Dependency injection method in React source code

<<:  The submit event of the form does not respond

>>:  Summary of the use of MySQL date and time functions

Recommend

How to prompt and open hyperlink a

<br />The countless information on the Inter...

Implementation code of using select to select elements in Vue+Openlayer

Effect picture: Implementation code: <template...

Installation and use of mysql mycat middleware

1. What is mycat A completely open source large d...

Application of CSS3 animation effects in activity pages

background Before we know it, a busy year is comi...

Detailed explanation of MySQL database (based on Ubuntu 14.0.4 LTS 64 bit)

1. Composition and related concepts of MySQL data...

Use HTML and CSS to create your own warm man "Dabai"

The final result is like this, isn’t it cute… PS:...

Analysis of the usage of Xmeter API interface testing tool

XMeter API provides a one-stop online interface t...

What is the function of !-- -- in HTML page style?

Mainly for low version browsers <!-- --> is ...

jQuery implements all shopping cart functions

Table of contents 1. Select All 2. Increase or de...

Will the deprecated Docker be replaced by Podman?

The Kubernetes team recently announced that it wi...

Detailed explanation of several ways to create objects and object methods in js

This article is the second article about objects ...

Three ways to jump to a page by clicking a button tag in HTML

Method 1: Using the onclick event <input type=...

mysql query data for today, this week, this month, and last month

today select * from table name where to_days(time...