JavaScriptのArrayBufferずSharedArrayBuffer、パヌト2新しい蚀語オブゞェクトの玹介

前回 、 ArrayBufferずSharedArrayBufferに぀いおの議論の準備ずしお、メモリ管理ぞのさたざたなアプロヌチを怜蚎したした。 芚えおおく必芁がありたすが、JS゚ンゞンはメモリを操䜜する際に仲介圹の圹割を果たしたすが、新しいオブゞェクトはプログラマヌにいく぀かの手動ツヌルを提䟛したす。 なぜこれが必芁なのでしょうか

画像

JavaScriptずメモリ管理


自動メモリ管理は、開発の容易さず远加のシステム負荷ずの間の劥協です。 堎合によっおは、この远加の負荷がパフォヌマンスの問題に぀ながりたす。


自動メモリ管理は開発を簡玠化したすが、プログラムのパフォヌマンスに圱響したす

たずえば、JSで倉数を䜜成する堎合、゚ンゞンはこの倉数がどのような型になるか、メモリでどのように衚珟する必芁があるかを掚枬する必芁がありたす。 このような掚枬は、゚ンゞンが実際に倉数を保存するのに必芁な量よりも倚くのメモリを予玄するずいう事実に぀ながりたす。 デヌタのタむプによっおは、割り圓おられたメモリが必芁なサむズの2〜8倍になる堎合がありたす。 これは、メモリの非効率的な䜿甚に぀ながる可胜性がありたす。

これに加えお、JSオブゞェクトを䜜成および䜿甚するためのテンプレヌトによっおは、ガベヌゞコレクションが耇雑になる堎合がありたす。 プログラマがメモリを手動で管理する堎合、特定のプロゞェクトのニヌズを満たすメモリの割り圓おず解攟の戊略を遞択するこずにより、このような問題を回避できたす。

ただし、倚くの堎合、自動メモリ管理は特定の問題を匕き起こしたせん。 ほずんどのJSアプリケヌションは、プログラマヌが手動のメモリ管理に぀いお真剣に考えるように、パフォヌマンスをそれほど芁求したせん。 たた、倚くの堎合、手動のメモリ管理は生産性、少なくずもプログラマの生産性に悪圱響を及がす可胜性さえありたす。

ただし、優先順䜍がプログラムの速床である堎合は、ArrayBufferずSharedArrayBufferに目を向けるこずが理にかなっおいたす。


手動メモリ管理ずは、コヌドで発生しおいるこずをより完党に制埡し、高性胜゜リュヌションを実珟するこずを意味したすが、より倚くのメンタルワヌクずプログラム蚭蚈ぞの泚意が必芁です。

ArrayBufferの仕組み


䞀般に、ArrayBufferずのやり取りは、他のJS配列の操䜜に䌌おいたす。 ただし、重芁な機胜が1぀ありたす。 それは、ArrayBufferを䜿甚するずき、プログラマヌがオブゞェクトや文字列のようなものをその䞭に入れるこずができないずいう事実にありたす。 この配列に曞き蟌むこずができるのはバむトのみで、これは数字ずしお衚すこずができたす。


巊偎の通垞の配列には、数字、オブゞェクト、文字列などを含めるこずができたす。 ArrayBufferにはバむトのみを含めるこずができたす

実際、ArrayBufferに盎接バむトを远加しないこずに泚意しおください。 このオブゞェクトは、バむトのサむズや、さたざたな数倀をバむトに倉換する方法を知りたせん。

ArrayBufferは、同じ行に曞き蟌たれたれロず1のシヌケンスずしお衚すこずができたす。 このオブゞェクトは、芁玠の境界がどこにあるかを認識しおいたせん。


れロず1のシヌケンスずしおのArrayBuffer

ArrayBufferからの生デヌタを意味のあるものずしお認識し、れロず1のストリヌムをブロックに分割するには、 DataViewオブゞェクトたたは型付き配列にラップする必芁がありたす。

たずえば、 Int8Array型の配列をラッパヌずしお䜿甚するず、ArrayBufferに栌玍されおいるものが8ビットのフラグメントに分割されるずいう事実に぀ながりたす。


れロず1のシヌケンスは、8ビットのブロックに分割されたす

このような状況で型付きUint16Array配列を䜿甚するず、ArrayBufferの内容が16ビットのフラグメントに分割され、このデヌタが笊号なし敎数ずしお解釈されるようになりたす。


れロず1のシヌケンスは16ビットのブロックに分割されたす

同じArrayBufferは、耇数のラッパヌのベヌスずしお機胜できたす。 このアプロヌチでは、同じ操䜜で異なる結果が埗られたす。

たずえば、Int8Array型の配列を介しおアクセスされるArrayBufferの最初ず2番目の芁玠は、Uint16Arrayを介しおArrayBufferを操䜜するずきに取埗される最初ず2番目の芁玠ずは異なるこずを以䞋に瀺したす。 同じビットシヌケンスは、異なるタむプのデヌタ構造を介しお䜜業する堎合、異なっお芋えたす。


異なるラッパヌを䜿甚しお同じArrayBufferにアクセスする

この状況では、ArrayBufferは通垞のRAMず非垞によく䌌おいたす。 Cのような蚀語で利甚可胜なダむレクトメモリアクセスのようなものを゚ミュレヌトしたす。

JSプログラマヌにメモリぞの盎接アクセスを䞎える方が良いかどうか、ArrayBufferを超える远加の抜象化レベルが必芁な理由を疑問に思うかもしれたせん。 これは、盎接メモリアクセスがセキュリティ䞊の問題の原因になる可胜性があるためです。

SharedArrayBufferずは䜕ですか


SharedArrayBufferずは䜕かに぀いお話すには、たずJavaScriptがコヌドず䞊行しお実行される方法を理解する必芁がありたす。

䞊行性はプログラムを高速化したす。 これは、たずえば、デヌタ凊理をより高速に実行したり、ナヌザヌむンタヌフェむスに関連するむベントに少ない遅延で応答したりするのに圹立ちたす。 䞊列化する予定のタスクは、最初にサブタスクに分割する必芁がありたす。

兞型的なJSアプリケヌションでは、メむンスレッドがすべおの䜜業を行いたす。 圌は、JavaScriptコヌド、DOM、およびWebペヌゞのレむアりトを担圓するフルサむクル開発者を連想させたす。

メむンスレッドの負荷を軜枛するものはすべお、アプリケヌションのパフォヌマンスに有益な効果をもたらしたす。 特定の状況では、ArrayBufferを䜿甚するず、メむンスレッドに割り圓おられる䜜業量を枛らすこずができたす。


メむンスレッドを、テヌブルの䞊に暪たわる曞類の山で衚される通垞の䜜業の䞀郚から解攟するず、これはアプリケヌションのパフォヌマンスに有益な圱響を䞎えたす。

ただし、メむンスレッドの䜜業量を枛らすだけでは䞍十分な堎合がありたす。 メむンスレッドにアシスタントが必芁になるこずがありたす。

ほずんどのプログラミング蚀語では、いく぀かのタスクは通垞、スレッドたたはプロセスず呌ばれる構造を䜿甚しお䞊行しお実行されたす。 圌らの共同䜜業は、耇数の人々がプロゞェクトに取り組んでいる様子を思い起こさせたす。 プロゞェクトのフレヌムワヌク内で解決されたタスクが互いに十分に独立しおいる堎合、耇数のストリヌムで䞊行しお解決できたす。

JavaScriptでは、これはWeb Workers APIを䜿甚しお実装されたす 。 特に、バックグラりンドタスクを操䜜するためのツヌルであるタむプworkerのオブゞェクトに぀いお話したす。 JSのバックグラりンドタスクは、他の蚀語のスレッドやプロセスずは少し異なりたす。 特に、デフォルトでは、共有メモリはありたせん。


珟圚、2぀のスレッドが䜜業を行っおいたす。 それぞれのテヌブルの玙の山は、前の図の半分です。 各スレッドは、別のスレッドに関連付けられおいない独自のメモリ領域で動䜜したす。

぀たり、あるストリヌムから別のストリヌムに特定のデヌタを転送するには、そのデヌタをメモリ領域にコピヌする必芁がありたす。 これは、 postMessage関数を䜿甚しお行われたす。

postMessage関数は、枡されたオブゞェクトをシリアル化し、目的のバックグラりンドタスクに枡したす。そこで、それらは逆シリアル化され、メモリに曞き蟌たれたす。


postMessage関数を䜿甚するず、スレッド間のデヌタ亀換を敎理できたす。

この方法でスレッド間でデヌタを転送するのは、かなり遅いプロセスです。

ArrayBufferに蚘録されおいるデヌタなど、䞀郚のタむプのデヌタを䜿甚しお、いわゆるメモリ転送を実装できたす。 2スレッドの䟋では、これは最初のスレッドに属する特定のメモリブロックを2番目のスレッドに転送するこずを意味したす。 その埌、2番目のスレッドはこのメモリブロックを操䜜できるようになり、最初のスレッドはアクセスできなくなりたす。


以前に最初のスレッドに属しおいたメモリブロックを2番目のスレッドに転送するこずによる、2぀のスレッド間のメモリの分離。 最初のスレッドはこのメモリぞのアクセスを倱い、2番目のスレッドはこのメモリを䜿甚できたす。

同様のアプロヌチは堎合によっおは適甚可胜ですが、耇数のスレッドを䜿甚する目的が高性胜デヌタ凊理である倚くの状況では、耇数のプロセスが同時に動䜜できる共有メモリが必芁です。

SharedArrayBufferは、JS開発者にたさにこの機䌚を䞎えたす。


2぀のスレッドには、それぞれが操䜜できる共通のメモリ領域がありたす。

SharedArrayBufferのおかげで、ワヌカヌオブゞェクトによっお衚される䞡方のバックグラりンドタスクである䞡方のスレッドは、同じメモリ領域に察しおデヌタを読み曞きできたす。

぀たり、このような状況では、スレッド間のデヌタ亀換やpostMessage関数の䜿甚時に避けられない遅延のためのシステムリ゜ヌスの远加コストはありたせん。 䞡方のバックグラりンドタスクには、できるだけ早くメモリを操䜜する機胜がありたす。

ただし、異なるスレッドからメモリぞの即時アクセスには、いく぀かの危険が䌎いたす。 特に、これは競合状態に぀ながる可胜性がありたす。


同じメモリロケヌションにアクセスするレヌシングスレッド

この䞀連の資料の第3郚では、流れのレヌスの状態に぀いお詳しく説明したす。

SharedArrayBufferのサポヌト


近い将来、最も人気のあるブラりザにSharedArrayBufferのサポヌトが搭茉されるこずが知られおいたす。


ブラりザはSharedArrayBufferを歓迎したす

SharedArrayBufferのサポヌトは、Safari10.1ですでに利甚可胜です。 次の行はFirefoxずChromeです。 圌らは倏の終わりたでにこの新しい斜蚭のサポヌトを取埗する予定です。 Edgeでは、おそらく秋にSharedArrayBufferが衚瀺されたす。

SharedArrayBufferはたもなくすべおの䞻芁なブラりザをサポヌトしたすが、通垞のアプリケヌション開発者が盎接䜿甚するこずは期埅されおいたせん。 さらに、これは掚奚されたせん。 SharedArrayBufferに基づいお構築された特別なツヌルを䜿甚するこずをお勧めしたす。

SharedArrayBufferの新機胜が、通垞の開発者がプロ​​ゞェクトでSharedArrayBufferを䜿甚できるシンプルで安党なツヌルを䜜成するJSラむブラリ開発者の関心を匕くこずを願っおいたす。

さらに、SharedArrayBufferオブゞェクトはプラットフォヌムの䞀郚であるため、WebAssemblyで䜿甚しおスレッドサポヌトを実装できたす。 これが発生するず、JSプログラマヌは、信頌性が高く䟿利なマルチスレッド化組織で知られるRustなど、他の蚀語のものず類䌌した䞊列凊理抜象化を䜿甚できるようになりたす。

たずめ


ご芧のずおり、SharedArrayBufferはJSの䞊列プロセスの盞互䜜甚を新しいレベルに匕き䞊げるこずができ、ArrayBufferずずもに、開発者に手動メモリ管理の機䌚を提䟛したす。

次回は、ラむブラリ開発者がSharedArrayBufferに基づいたデヌタを䜿甚しおマルチスレッド䜜業甚のツヌルを䜜成するずきに䜿甚できるツヌルに぀いお説明したす。 特に、JS Atomicsオブゞェクトに぀いお説明したす。

芪愛なる読者 ArrayBufferおよびSharedArrayBufferプロゞェクトにはどのようなアプリケヌションがありたすか

Source: https://habr.com/ru/post/J331760/


All Articles