この記事では、Node.js のバッファを理解し、バッファ構造、バッファ メモリ割り当て、バッファ スプライシングなどについて説明します。皆さんのお役に立てれば幸いです。
#バッファについて理解する
JavaScript文字列操作に非常に適しています
は Array
のようなオブジェクトで、主にバイトの操作に使用されます。
Buffer
は、JavaScript と C を組み合わせた代表的なモジュールです。パフォーマンスに関連する部分は C で実装され、それ以外の部分は C で実装されます。パフォーマンス関連の部分は C で実装されています。一部は JavaScript で実装されています。
#Buffer によって占有されるメモリは V8 を通じて割り当てられず、オフヒープ メモリに属します。 V8 ガベージ コレクションはパフォーマンスに影響を与えるため、より効率的で独自のメモリ割り当てとリサイクル ポリシーを使用して、一般的に使用される操作オブジェクトを管理することをお勧めします。
Buffer オブジェクト
Buffer オブジェクトの要素は 2 桁の 16 進数ではなく、つまり、0 ~ 255
let buf01 = Buffer.alloc(8); console.log(buf01); // <Buffer 00 00 00 00 00 00 00 00>
の値です。
fill を使用して buf の値を埋めることができます (デフォルトは utf-8
エンコードです)。値がバッファを超えると、書き込まれません。
以前に埋められたコンテンツをクリアしたい場合は、直接fill を実行できます。 ()
<pre class='brush:php;toolbar:false;'>buf01.fill(&#39;12345678910&#39;)
console.log(buf01); // <Buffer 31 32 33 34 35 36 37 38>
console.log(buf01.toString()); // 12345678</pre>
記入内容が中国語の場合、
の影響で、3要素に漢字が入り、文字と半角句読点が入ります。 1要素を占有します。 <pre class='brush:php;toolbar:false;'>let buf02 = Buffer.alloc(18, &#39;开始我们的新路程&#39;, &#39;utf-8&#39;);
console.log(buf02.toString()); // 开始我们的新</pre>
は Array type
によって大きく影響されます。長さ属性にアクセスして長さを取得したり、添字を使用して要素にアクセスしたりすることもできます。また、indexOf を通じて要素の位置を表示することもできます。 <pre class='brush:php;toolbar:false;'>console.log(buf02); // <Buffer e5 bc 80 e5 a7 8b e6 88 91 e4 bb ac e7 9a 84 e6 96 b0>
console.log(buf02.length) // 18字节
console.log(buf02[6]) // 230: e6 转换后就是 230
console.log(buf02.indexOf(&#39;我&#39;)) // 6:在第7个字节位置
console.log(buf02.slice(6, 9).toString()) // 我: 取得<Buffer e6 88 91>,转换后就是&#39;我&#39;</pre>
バイトに割り当てられた値が 0
255 の整数の間の値を取得します。 255 より大きい場合は、255 を 1 つずつ減算します。小数の場合は、小数部分を切り捨てます (四捨五入なし)
バッファ メモリ割り当てバッファ
オブジェクトのメモリ割り当ては、 V8 ヒープ内 メモリ内では、メモリ アプリケーションはノードの C レベルで実装されます。大量のバイト データを処理する場合、メモリが必要なときにオペレーティング システムからメモリを申請できないためです。このため、Node は C レベルのメモリを使用して JavaScript
で スラブ割り当てメカニズムを採用します
, slab
は動的メモリ管理メカニズムであり、現在 Linux
slab
などの一部の
オペレーティング システムで広く使用されています。スラブには次の 3 つの状態があります:
- partial: 部分的な割り当てステータス
- empty: 割り当てられていないステータス
- ノードは、バッファがラージ オブジェクトかスモール オブジェクトかを区別するための制限として
を使用します。console.log(Buffer.poolSize); // 8192
#小さなバッファ オブジェクトを割り当てます
指定された Buffer
サイズが 8KB 未満の場合、ノードはスモール オブジェクト メソッド に従ってサイズを割り当てます。新しいスラブ ユニットを構築します。スラブは現在空の状態です。
1024KB の小さな
- オブジェクトを構築します。現在の
- slab
は 1024KB で占有されます。レコードはどこからのものです この
slabはどこから使用され始めますか?
この時点で、
- オブジェクト。構築プロセスでは、現在の
- slab
の残りのスペースが十分であるかどうかが判断され、十分な場合は、残りのスペースを使用して、
slabの割り当てステータスを更新します。 3072KB のスペースが使用された後、このスラブの残りのスペースは現在 4096KB です。
この時点で 6144KB のサイズの
- を作成すると、現在のスラブ領域では不十分であり、新しいスラブ領域が
- スラブが構築されます
(これにより、元のスラブの残りのスペースが無駄になります)
たとえば、次のようになります。例: ###
Buffer.alloc(1) Buffer.alloc(8192)
第一个slab
中只会存在1字节的buffer对象,而后一个buffer对象会构建一个新的slab存放
由于一个slab可能分配给多个Buffer对象使用,只有这些小buffer对象在作用域释放并都可以回收时,slab的空间才会被回收。 尽管只创建1字节的buffer对象,但是如果不释放,实际是8KB的内存都没有释放
小结:
真正的内存是在Node的C++层面提供,JavaScript层面只是使用。当进行小而频繁的Buffer操作时,采用slab的机制进行预先申请和时候分配,使得JavaScript到操作系统之间不必有过多的内存申请方面的系统调用。 对于大块的buffer,直接使用C++层面提供的内存即可,无需细腻的分配操作。
Buffer的拼接
buffer在使用场景中,通常是以一段段的方式进行传输。
const fs = require('fs'); let rs = fs.createReadStream('./静夜思.txt', { flags:'r'}); let str = '' rs.on('data', (chunk)=>{ str += chunk; }) rs.on('end', ()=>{ console.log(str); })
以上是读取流的范例,data时间中获取到的chunk对象就是buffer对象。
但是当输入流中有宽字节编码(一个字占多个字节
)时,问题就会暴露。在str += chunk
中隐藏了toString()
操作。等价于str = str.toString() + chunk.toString()
。
下面将可读流的每次读取buffer长度限制为11.
fs.createReadStream('./静夜思.txt', { flags:'r', highWaterMark: 11});
输出得到:
上面出现了乱码,上面限制了buffer长度为11,对于任意长度的buffer而言,宽字节字符串都有可能存在被截断的情况,只不过buffer越长出现概率越低。
encoding
但是如果设置了encoding
为utf-8
,就不会出现此问题了。
fs.createReadStream('./静夜思.txt', { flags:'r', highWaterMark: 11, encoding:'utf-8'});
原因: 虽然无论怎么设置编码,流的触发次数都是一样,但是在调用setEncoding
时,可读流对象在内部设置了一个decoder对象
。每次data事件都会通过decoder对象
进行buffer到字符串的解码,然后传递给调用者。
string_decoder
模块提供了用于将 Buffer 对象解码为字符串(以保留编码的多字节 UTF-8 和 UTF-16 字符的方式)的 API
const { StringDecoder } = require('string_decoder'); let s1 = Buffer.from([0xe7, 0xaa, 0x97, 0xe5, 0x89, 0x8d, 0xe6, 0x98, 0x8e, 0xe6, 0x9c]) let s2 = Buffer.from([0x88, 0xe5, 0x85, 0x89, 0xef, 0xbc, 0x8c, 0x0d, 0x0a, 0xe7, 0x96]) console.log(s1.toString()); console.log(s2.toString()); console.log('------------------'); const decoder = new StringDecoder('utf8'); console.log(decoder.write(s1)); console.log(decoder.write(s2));
StringDecoder
在得到编码之后,知道了宽字节字符串在utf-8
编码下是以3个字节的方式存储的,所以第一次decoder.write
只会输出前9个字节转码的字符,后两个字节会被保留在StringDecoder
内部。
Buffer与性能
buffer在文件I/O和网络I/O中运用广泛,尤其在网络传输中,性能举足轻重。在应用中,通常会操作字符串,但是一旦在网络中传输,都需要转换成buffer,以进行二进制数据传输。 在web应用中,字符串转换到buffer是时时刻刻发生的,提高字符串到buffer的转换效率,可以很大程度地提高网络吞吐率。
如果通过纯字符串的方式向客户端发送,性能会比发送buffer对象更差,因为buffer对象无须在每次响应时进行转换。通过预先转换静态内容为buffer对象,可以有效地减少CPU重复使用,节省服务器资源。
可以选择将页面中动态和静态内容分离,静态内容部分预先转换为buffer的方式,使得性能得到提升。
在文件的读取时,highWaterMark
设置对性能影响至关重要。在理想状态下,每次读取的长度就是用户指定的highWaterMark
。
highWaterMark
大小对性能有两个影响的点:
- 对buffer内存的分配和使用有一定影响
- 设置过小,可能导致系统调用次数过多
更多node相关知识,请访问:nodejs 教程!!
以上がNode.js の Buffer モジュールを簡単に理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

ホットトピック









