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

Vue must learn knowledge points: the use of forEach()

Preface In front-end development, we often encoun...

Detailed explanation of common methods of Vue development

Table of contents $nextTick() $forceUpdate() $set...

Code analysis of user variables in mysql query statements

In the previous article, we introduced the MySQL ...

MySQL 5.7.20 free installation version configuration method graphic tutorial

I have seen many relevant tutorials on the Intern...

One line of code solves various IE compatibility issues (IE6-IE10)

x-ua-compatible is used to specify the model for ...

MySQL free installation version configuration tutorial

This article shares the MySQL free installation c...

Implementation of grayscale release with Nginx and Lua

Install memcached yum install -y memcached #Start...

Vue realizes the whole process of slider drag verification function

Rendering Define the skeleton, write HTML and CSS...

HTML form tag tutorial (3): input tag

HTML form tag tutorial, this section mainly expla...

Zabbix uses PSK shared key to encrypt communication between Server and Agent

Since Zabbix version 3.0, it has supported encryp...

Basic commands for MySQL database operations

1. Create a database: create data data _name; Two...

How to set mysql permissions using phpmyadmin

Table of contents Step 1: Log in as root user. St...