PHPのオブゞェクトのコレクション。 パヌト2

PHPのオブゞェクトのコレクションに関する最初の投皿が公開されおから、ほが3週間が経過したした。 この間、倚くの䜜業が行われ、倚くの経隓が埗られたした。これを共有したいず思いたす。 カヌドはほずんどの倉曎を受け、ほずんどの泚意がそれらに払われたす。

この投皿では次のように衚瀺されたす。



䜕がされたしたか



最埌の投皿の公開ずその議論の終了埌、私はさらなる開発の蚈画を立おたした。


䞊蚘のリストに加えお、珟圚のリリヌス蚈画に含たれおいない候補者もいたした。



収集むンタヌフェヌス


以前に開発されたコレクションむンタヌフェむスは、新しい開発蚈画に非垞に着実に察応しおいたす。 珟圚のバヌゞョンのむンタヌフェヌス図は次のようになりたす。


図からわかるように、すべおのコレクションむンタヌフェむスはIteratorAggregateむンタヌフェむスを継承したす。これにより、foreachを䜿甚しおコレクションをトラバヌスできたす。 foreachを䜿甚しお<object-object>マップを凊理するずきにポップアップする譊告の問題は䟝然ずしお残っおいたすが、そのような状況は非垞にたれなので、私はこれに目を閉じるこずにしたした。

カヌドの実装


マップは、HashMap、HashSet、およびHashTableの実装によっお衚されたす。 これらの各実装には、䜿甚を簡玠化するための独自の特殊化がありたす。



ハッシュテヌブル

HashTableマップの内郚構造は、単䞀のPHP配列に基づいおいたす。 これにより、O1キヌをすばやく操䜜できたすが、通垞のOn反埩によっお実行される倀を操䜜する機胜に悪圱響を及がしたす。

HashTableカヌドのキヌは䞀意です。 HashTableマップの倀は䞀意ではないため、単䞀の倀を耇数のキヌに関連付けるこずができたす。

HashTableマップは、キヌず文字列の文字列ず敎数、倀の敎数ずオブゞェクトをサポヌトしたす。

キヌず倀のハッシュは実行されたせん。 getKeyHashおよびgetValueHashメ゜ッドは䟋倖をスロヌしたす。

HashTableクラス図。

ハッシュマップずハッシュセット

HashMapおよびHashSetマップの内郚構造は、連想リンクのネットワヌクに基づいおいたす。 これにより、連想サンプルを䜿甚しおすべおのマップ操䜜を実装できたす。 マップアルゎリズムの䜜業の耇雑さはO1です。これは、オブゞェクトのむンストヌル/取埗時間がカヌドのサむズに応じお倉化しないこずを意味したす。

HashMapカヌドのキヌは䞀意です。 HashMapマップの倀は䞀意ではないため、単䞀の倀を耇数のキヌに関連付けるこずができたす。

HashSetマップのキヌず倀は䞀意であるため、䞀意の関連付けのリポゞトリを敎理できたす。

HashMapおよびHashSetカヌドは、文字列、敎数、およびキヌず倀のオブゞェクトをサポヌトしおいたす。

HashMapクラス図。
HashSetクラス図。

セット、リスト、およびキュヌの実装


セットの実装には、いく぀かの衚面的な倉曎が加えられおおり、単玔化された䜿甚のための専門化が倧きくなっおいたす。
チャヌトクラス図。

リストずキュヌの実装はほずんど倉曎されおいたせん。
リストずキュヌのクラス図。

機胜テスト


送信されたすべおのコヌドは、 PHPUnitテストでカバヌされたす。
これらは私の最初のナニットテストであり、この経隓に非垞に満足しおいたす。 このタむプのテストにより、実装を倉曎する必芁があった修正のために、玄10のタむプミスず1぀の基本的な゚ラヌをキャッチできたした。
次の3぀のこずに泚意しおください。
  1. ナニットテストをただ䜿甚しおいない堎合は、今すぐ開始したす。 個人的には、興味深い状況がありたした。倚くのコヌドを生成し、サポヌトする必芁があり、サポヌトしなければなりたせんでした。 なんで -ただ始めるのが怖い。 今になっおようやく、自分の人生がずっず楜になり埗るこずに気づきたした。
  2. 最初のいく぀かのテストを曞いた埌、私は倧きな、未開拓の私にずっお䞖界が内郚にあるこずに気付きたした。 さたざたなassert *のうち、䜿甚したのはほんのわずかです。 倚くの堎合、テストコヌドは効率的でなく、重耇しおいたす。 PHPUnitのドキュメントを䞀目芋ただけで、䜜成したテストよりもテストの方がはるかに優れおいるこずがわかりたした。
  3. ナニットテストはすべおの病気を治すわけではありたせん。 メ゜ッド、その䞭のすべおのロゞックをテストできたす。特定の小さなシナリオをテストするための䟿利なプラットフォヌムもありたすが、他のテスト方法を忘れないでください。 適切に自動化できるものから、远加のテストオプションずしお動䜜テストを遞択したす。


性胜詊隓


私にずっお最も興味深いのは、コレクションの生産性です。 セットずシヌケンシャルリストの実装は砎棄し、マップのテストに焊点を合わせたした。

テストオブゞェクト

テスト基準


テストプラットフォヌムの詳现に぀いおは説明したせん。これはあたり意味がないためです。 実際、これらのテストは定量的特性を決定するこずを目的ずしおおらず、むしろ比率を瀺すこずを目的ずしおいたす。 テスト結果の比率は、異なるハヌドりェアたたは異なるオペレヌティングシステムでは実際には倉化したせんでした。
この投皿のテスト結果は、Windows Vista 32ビットのラップトップから撮圱したした。

キヌ/倀ペアのむンストヌル時間のテスト

チャヌト

テストファむル

キヌ取埗時間のテスト

チャヌト

テストファむル

倀によるキヌ取埗時間のテスト

チャヌト

テストファむル

消費されるRAMの量をテストする

チャヌト

テストファむル


いく぀かの興味深い事実


その過皋で、共有したい興味深い事実がいく぀か浮䞊したした。

䞍敎合spl_object_hash

倚くの人がspl_object_hash関数に粟通しおいるず思いたす。
私の意芋では、圌女には非垞に優れた機胜ではないものがありたす-ハッシュ䞍敎合。

䞍敎合テストspl_object_hast
<?php $object1 = new stdClass(); $hash1 = spl_object_hash($object1); unset($object1); $object2 = new stdClass(); $hash2 = spl_object_hash($object2); var_dump($hash1); var_dump($hash2); var_dump($hash1 === $hash2); //string '000000004974d03c000000005560c408' (length=32) //string '000000004974d03c000000005560c408' (length=32) //boolean true 

これから䜕が起こり、なぜこの機胜が䞍快なのですか

私ず私の仕事にずっお、この動䜜は適切ではありたせんでした。オブゞェクトの高速ハッシュの゜ヌスずしおこの関数に正確に䟝存しおいたからです。

配列キヌの内郚ハッシュ

私の最埌の投皿のコメントで、 Athariは貎重なコメントを残したした。その䞀郚を匕甚したす。

なぜ文字列のmd5を蚈算するのですか Pokhashny配列-ハッシュテヌブルなので、2぀のレベルでハッシュを蚈算する必芁はありたせん。 メモリずコンピュヌティングリ゜ヌスのみが無駄になりたす。


これには本圓に倚くの意味がありたすが、それでも確認するこずにしたした。
結果


配列のハッシュ化

同じAthariナヌザヌが最埌の投皿に別の賢明なコメントを残したした。
シリアラむズ呌び出しは面癜いです。 すべおのタむプをサポヌトするこずは「必芁」ですが、同じ䟡栌ではないこずを理解しおいたす。

コンテキストを再䜜成するには、コレクションのキヌのデヌタ型ずしお配列をサポヌトする必芁があるずいう事実に぀いお話しおいたこずを思い出させおください。 これを行うために、文字列にキャストするようにシリアル化され、md5を䜿甚しおこの文字列をハッシュしたした。

本圓に「高䟡な」䟡栌。 珟圚の実装では、配列をマップキヌずしおサポヌトするこずを完党に拒吊したした。

配列のサポヌトを拒吊した理由


特に「安党ではない」ずいう項目で停止したいず思いたす。ポむントは、デヌタずハッシュの間のフィヌドバックが䞍足しおいるこずです「高䟡」に関係なく。 クラむアントコヌドが、ハッシュした配列ぞの参照を保持し、それを倉曎するず、ハッシュは廃止されたす。 これは同じ機䌚の配列ではないずいう情報を入手しおください。 同じこずが他のスカラヌデヌタ型にも圓おはたりたす。

抜け道はありたすか 頭に浮かぶのは、オブゞェクトラッパヌArrayObjectなどを介しお配列を䜿甚するこずだけです。 この堎合、少なくずも "fickle"のspl_object_hashを取埗できたす。

おわりに


おそらく、答える必芁がある最も重芁な質問は、「この゜リュヌションの生産性の芳点からそのような䟡栌を支払う準備ができおいたすか」です。 誰も準備ができおいないず確信しおいたす。 そしお私も含めお。 パフォヌマンステストの結果のグラフを䜜成したずき、私は驚きたした。 暙準的な実装ず比范しおはるかに䜎い比率を期埅しおいたしたが、この偎面ではこの゜リュヌションが明らかに倱われるこずを完党に理解しおいたした。 最初は問題の解決策を芋぀けようずさえしたしたが、残念ながら、䜕も起こりたせんでした。 䞻な問題は、この堎合、メ゜ッド呌び出しでさえ「高䟡な」操䜜であるずいうこずです。 消費されるRAMの量に関しおは、私はそれがそれほど倚くのリ゜ヌスを必芁ずするかをただ理解しおいたせん。 唯䞀の有甚な革新は、カヌドの双方向ハッシュです。これにより、O1のフレヌムワヌク内の倀で遞択できたす。

䞀般に、私はこのプロゞェクトが倱敗したず信じおおり、その理由はパフォヌマンスの面にありたす。

開発

私の分析に基づいお、このような゜リュヌションは今埌も衚瀺されたす。 圌にずっお最適な堎所はSPLパッケヌゞです。 SPLではなく、他のPECLモゞュヌルであり、最終的には暙準のPHPアセンブリの䞀郚になるでしょう。 いずれにせよ、Cでの有胜な実装によっおのみ満足のいくものが埗られたす。ちなみに、誰かがこのプロゞェクトに興味があり、PECLモゞュヌルずしおの実装を支揎したい堎合は、喜んで協力したす。

次に䜕をする

たぶん、私たちが今持っおいるものに満足しお埅っおください。 結局のずころ、今でもすべおがかなり良いです。

個人的には、日垞生掻で少し圹立぀だけで、暙準のPHP配列以䞊の軜量な実装を䜜成するこずにしたした。 すでにいく぀かのドラフトがありたす

クラス図
MixedArrayおよびObjectArray UML図

゜ヌスコヌド
MixedArray
ObjectArray

これが誰かにずっお興味深い堎合は、曞いお、私はより詳现にアむデアに぀いお話したす。

゜ヌスコヌド


https://github.com/rmk135/Rmk-Framework

謝蟞


前回の投皿に察する建蚭的なコメントに感謝したす。 圌らはずおも圹に立ちたした。 もう䞀床ご意芋をお聞かせください。

最埌たで読んでくれおありがずう、豊富なグラフィックスでごめんなさい、私はそれを必芁な堎所にのみ配眮しようずしたした。

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


All Articles