Reactソースコードにおけるビット演算について詳しく説明します

Reactソースコードにおけるビット演算について詳しく説明します

序文

過去 2 年間、多くの友人が React のソース コードについて次のような不満を私に伝えてきました。

  • スケジューラはなぜ配列ではなくミニヒープのようなデータ構造を使用するのでしょうか?
  • ソースコードには一方向リンクリストや循環リンクリストがいろいろありますが、配列を使えばいいのではないでしょうか?
  • ソースコード内の各種ビット操作は必要ですか?

ビジネスに依存するフレームワークである React は、実行時のパフォーマンスを少しでも向上させるために、ソース コードを複雑にすることを躊躇しません。

ビット操作は、ステータス、フラグ ビット、および優先度操作が関係する場所で広く使用されます。
この記事では、それらのより代表的な部分について説明します。それを学んだ後、同様のシナリオに遭遇したときにあなたのスキルを披露すれば、あなたのビジネスラインで最も印象的な人物になるでしょう。

いくつかの一般的なビット操作

JS では、ビット演算のオペランドはまず Int32 (32 ビット符号付き整数) に変換され、ビット演算が実行された後、Int32 の対応する浮動小数点数が変換されます。

React では、ビット AND、ビット OR、ビット NOT という 3 つの主要なビット演算子が使用されます。

ビットAND (&)

2 つのバイナリオペランドの各ビットについて、両方のビットが 1 の場合、結果は 1 になり、それ以外の場合は 0 になります。

たとえば、3 と 2 を計算するには、まずオペランドを Int32 に変換します。

// 3に対応するInt32
0b000 0000 0000 0000 0000 0000 0000 0011 
// 2に対応するInt32
0b000 0000 0000 0000 0000 0000 0000 0010 

直感的に分かりやすくするために、先頭の 0 を除外し、最後の 8 ビットのみを保持します (計算に関係する実際のビット数は 32 ビットです)。

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

したがって、3 と 2 を浮動小数点数に変換すると、結果は 2 になります。

ビットOR (|)

2 つのバイナリオペランドの各ビットについて、両方のビットが 0 の場合、結果は 0 になり、それ以外の場合は 1 になります。

10 | 3を計算します:

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

計算結果は浮動小数点数に変換され、11になります。

ビット否定(~)

バイナリオペランドの各ビットに対して、ビットごとの反転演算を実行します(0と1が入れ替わります)。

~3 の場合、3 を Int32 に変換し、各ビットを反転します。

// 3に対応するInt32
0b000 0000 0000 0000 0000 0000 0000 0011 
// ビット反転 0b111 1111 1111 1111 1111 1111 1111 1100

計算結果を浮動小数点数に変換すると-4になります。

この結果に困惑している場合は、補完コードの知識を学ぶことができます。

React でのビット演算の応用を簡単なものから難しいものまで見てみましょう。

マークステータス

React のソースコードには複数のコンテキストがあり、関数を実行するときに、現在どのコンテキストにあるかを判断する必要があることがよくあります。

次の 3 つのコンテキストがあると仮定します。

// コンテキスト const A = 1;
// B コンテキスト const B = 2;
// コンテキスト内ではありません const NoContext = 0;

コンテキストを入力するときに、ビット単位の OR 演算を使用してエントリをマークできます。

// 現在のコンテキスト let curContext = 0;

// コンテキスト A に入る curContext |= A;

8 ビット バイナリを例として使用し (ここでも、実際には Int32 である必要がありますが、これは簡潔にするためです)、curContext と A に対してビット単位の OR 演算を実行します。

  0000 0000 // 現在のコンテキスト
| 0000 0001 // あ
-----------
  0000 0001

この時点で、ビット単位の AND 演算と NoContext を組み合わせて、特定のコンテキストにいるかどうかを判断できます。

// コンテキスト A にあるか? true
(現在のコンテキスト & A) !== コンテキストなし

// コンテキスト B にあるか? false
(現在のコンテキスト & B) !== コンテキストなし

コンテキストを離れた後、ビット単位の AND とビット単位の NOT を組み合わせてマークを削除します。

// 現在のコンテキストからコンテキスト A を削除します
curContext は、

// コンテキスト A にあるか? false
(現在のコンテキスト & A) !== コンテキストなし

curContext は ~A とビット単位の AND 演算を実行します。

  0000 0001 // 現在のコンテキスト
& 1111 1110 // ~A
-----------
  0000 0000

つまり、curContext から A を削除します。

ビジネスで複数の状態を同時に処理する必要がある場合は、上位操作などの手法を使用できます。

優先度計算

React では、さまざまな状況で this.setState を呼び出すことによってトリガーされる更新には、さまざまな優先順位があります。優先度の比較と選択にもビット演算が使用されます。
具体的には、React は更新を保存するために 31 ビットを使用します (32 ではなく 31 である理由は、Int32 の最上位ビットが符号ビットであり、特定の数値を保存しないためです)。

ビット位置が低いほど、更新の優先度が高くなります(最初に処理する必要があるものが多くなります)。

たとえば、現在のアプリケーションに 2 つの更新があるとします。

0b000 0000 0000 0000 0000 0000 0001 0001

更新優先度 1 が最も高く (同期処理が必要)、更新優先度 5 がデフォルトの優先度です。

React では、どの更新が最も優先度が高いか (上記の例では最初に) を調べる必要があることが多く、その方法は次のとおりです。

関数 getHighestPriorityLane(レーン) {
  戻りレーンと戻りレーン;
}

説明すると、Int32 は 2 の補数表現を使用するため、-lanes は次の 2 段階の操作として考えることができます。

  1. 車線否定 (~lanes)
  2. 1を追加

わかりやすくするために、8 ビットを使用します。

レーン 0001 0001
~lanes 1110 1110 // 最初のステップ + 1 1110 1111 // 2 番目のステップ

レーンと - レーンは次のようになります。

  0001 0001 // 車線  
& 1110 1111 // -レーン
-----------
  0000 0001

選択されるのは最初のもの(既存の更新の中で最も優先度が高いもの)です。

要約する

ビット操作はビジネスではあまり使用されませんが、特定のシナリオでは便利で効率的な方法です。

この操作は気に入っていますか?

Reactソースコードにおける中央値演算スキルに関するこの記事はこれで終わりです。Reactソースコードにおける中央値演算スキルに関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • ReactのsetStateソースコードの詳細な研究
  • React ソースコードにおける依存性注入方法

<<:  フォームの送信イベントが応答しない

>>:  イメージの起動時にdocker runまたはdocker restartが自動的に終了する問題を解決します

推薦する

MySQLはbinlogを通じてデータを復元する

目次MySQL ログファイルバイナリログBinlogログがオンになっていますログ記録を有効にする方法...

IE6 で PNG-24 形式の画像を正常に表示させる 2 つの方法

方法1: </html>の後に次のコードを追加してください。コードをコピーコードは次のと...

MySQLクエリキャッシュの簡単な使い方の詳細な説明

目次1. クエリキャッシュの実装プロセス2. クエリキャッシュを構成する3. クエリキャッシュを有効...

Linux で FTP イメージ サーバーをインストールして展開する方法

Linux で FTP サーバーを設定するためのチュートリアルを参照してください https://w...

プロジェクトにaxiosをカプセル化する実際のプロセス

目次序文axiosカプセル化の利点パッケージのアイデア設定の優先順位axiosインスタンス構成1. ...

MySQL で結合を使用して SQL を最適化する方法の詳細な説明

0. 以下のテストに関連する表を準備する関連するテーブル作成ステートメントについては、https:/...

マウスがカード上に移動したときにフローティング効果を実現する CSS の使用例

原理ホバーしたときに要素に影を設定します: box-shadow で、通常とは異なるスタイルにします...

適応レイアウトの処理について(フロートとマージンネガティブマージンを使用)

適応型レイアウトは、実際のアプリケーションでますます一般的になっています。今日は、主にフローティング...

ES6の新機能に関する最もよく使われる知識ポイントのまとめ

目次1. キーワード2. 脱構築3. 文字列4. 正規化5. 配列6. 機能7. オブジェクト8.シ...

Linux の chown コマンドと chmod コマンドの違いの詳細な説明

Linux システムでは、chmod コマンドと chown コマンドの両方を使用して権限を設定でき...

Vueのwatch、computed、methodsの違いのまとめ

目次1 はじめに2 基本的な使い方2.1 方法2.2 計算プロパティ2.3 リスナーを見る3 3つの...

Ubuntu Linux に Git と GitHub をインストールして使用する

Git 入門Git は、Linux(R) カーネル開発の管理を支援するために 2005 年に Lin...

Dockerでのpython3.8イメージのインストールについて

Docker Hub公式サイト1. Pythonミラーを検索するdocker 検索 python 2...

WeChatアプレットはユーザーログインモジュールサーバーの構築を実装します

サーバーの構築には node.js を選択しました。まだインストールしていない方は、私の他の nod...

Pagoda Panel のインストール時にサーバーがデータベースにリモート接続できない問題の解決策

自分のウェブサイトを構築する予定なので、618 プロモーションを利用して Tencent Cloud...