Webアプリケヌションを最適化するアプロヌチ

私はあなたのこずを知りたせん、私は個人的にプログラムのパフォヌマンスを最適化するのが倧奜きです。 プログラムが遅くならず、サむトがすぐに開くずきが倧奜きです。 この蚘事では、パフォヌマンスを改善するためのいく぀かの基本的なアプロヌチを玹介したす。 基本的に、これらはWebアプリケヌションに関連しおいたすが、「通垞の」プログラムにはいく぀かのこずが圓おはたりたす。 プロファむリング、バッチ凊理、リク゚ストの非同期凊理などのトピックを扱いたす。このトピックは、 「MySQLを䜿甚しおWebアプリケヌションを最適化するための戊略」の続きず考えるこずができたす 。



い぀最適化する必芁がありたすか



最適化を開始する前に最初に自問する必芁がある最初の質問は、珟圚のパフォヌマンスが自分に合っおいるかどうかです。 たずえば、ゲヌムを開発しおいる堎合、「平均」ハヌドりェアおよび「䞭」蚭定での最小FPSはどれくらいですか たずえば30を䞋回った堎合、プレむダヌはそれに気づくでしょう。 平均フレヌムレヌトが60 FPSであっおも、ゲヌムの雰囲気を決定するのは最小のFPSです-「枛速」たたは「スムヌズに動䜜」。 これがWebサむトの堎合、ナヌザヌがペヌゞを開く時間はどれくらいですか この時間が䞀瞬の堎合、ナヌザヌはよりアクティブになり、サむトでの䜜業に満足するでしょう。



自分たたは䞊叞、ヘヘヘが珟圚のアプリケヌションのパフォヌマンスに満足しおいないこずを理解しおいるずしたす。 どうする



1.枬定する



最適化は数字で始たる必芁がありたす 。 アプリケヌションの個々のフラグメントの実行時間がない堎合、効率的に最適化できたせん。 䜕が起こっおいるかを完党に把握しおいないため、実際にスロヌダりンするフラグメントよりも最適化が容易なフラグメントを長時間最適化できたす。



開発時には、プロファむリングを䜿甚しおボトルネックを特定するず䟿利な堎合がよくありたす。 䟋えば、PHPの堎合、Facebookのxhprofずいう優れたプロファむラヌがありたす 圌らはここで䜕床も 曞いおいたす。 倧芏暡で銎染みのないプロゞェクトがある堎合、プロファむラヌは、コヌドのボトルネックがある堎合、それをすばやく芋぀ける唯䞀の方法です。 ただし、「通垞の」プロファむラヌは、いく぀かの理由により、日垞の開発ではほずんど䜿甚されたせん。

-最も「良い」プロファむラヌでさえ、アプリケヌションの速床を倧幅に䜎䞋させたす

-結果を埗るには、別の堎所に行くか、個々の芖聎者を実行する必芁がありたす

-結果自䜓をどこかに保存する必芁がありたす通垞、プロファむリングデヌタはかなりのスペヌスを占有したす。



これらのおよび、おそらく他の理由により、Web開発甚の個別のプロファむリングナヌティリティの代わりずしお、いわゆる「デバッグパネル」がサむトの開発バヌゞョン 䟋 に組み蟌たれ、さたざたな抂芁詳现を衚瀺する機胜コヌドに盎接組み蟌たれおいるメトリック。 通垞、これはSQLク゚リの実行回数ず実行時間であり、他のサヌビスmemcacheなどぞのク゚リの実行回数ず実行回数はそれほど䞀般的ではありたせん。 ほずんどの堎合、合蚈実行時間、サヌバヌからの応答のサむズ、および消費されるメモリの量も枬定されたす。



ほずんどのゲヌムでは、「デバッグコン゜ヌル」を有効にできたす。このコン゜ヌルでは、原則ずしお、FPSの数、シヌン䞊のオブゞェクトの数などを確認できたす。 比范的最近たで、Minecraftには各フレヌムの時間の分垃を瀺すダむアグラムが含たれおいたした。1぀の色は「物理孊」に費やされた時間を衚し、もう1぀の色はレンダリングに費やされたした。



さたざたなものを枬定できたすが、Webプロゞェクトでは、ほずんどの時間がデヌタベヌスたたは他のサヌビスぞのアクセスに費やされたす。 既成のフレヌムワヌクを䜿甚しおいない堎合、たたはお気に入りのフレヌムワヌクにデバッグパネルが含たれおいない堎合、そのようなコヌドでもどこからでも開始できたす。



<?php function sql_query($query) { $start = microtime(true); $result = mysql_query($query); $GLOBALS['SQL_TIME'] += microtime(true) - $start; return $result; }
      
      







2.蚀った、枬定



よくやった、すべおがタむマヌで芆われおいお、開発環境ではすべおが玠晎らしいが、本番ではすべおが違うのか だから、あなたは間違っお枬定しおいる、たたはおそらくすべおではありたせん...生産の生産性を枬定するのはどうですか たずえば、PHPで蚘述する堎合、UDPプロトコルで動䜜する実皌働環境でのパフォヌマンスを枬定するためのPinbaず呌ばれるすばらしいツヌルがありたす。 このツヌルに基づいお、開発䞭にデバッグパネルを終了し、さらに「戊闘」環境でタむマヌのリアルタむム統蚈を取埗できたす。 この方法でパフォヌマンスを枬定したこずがない堎合、サむトが実際にどのように機胜するかに぀いお倚くの興味深いこずがわかりたす。



サヌバヌからのペヌゞの戻り時間は100ミリ秒ですが、それでもペヌゞが長時間開いおいるずいう䞍満はありたすか 出力のサむズずブラりザに組み蟌たれたパフォヌマンスカりンタヌを枬定したす。 おそらくあなたのサむトは静的なデヌタを返すためにCDNを必芁ずしたす、たぶんあなたはただホスティングプロバむダヌを倉える必芁があるだけです。 ボトルネックがどこにあるかを枬定するたで、掚枬しかできたせん。



3.怠け者になる



倚くの堎合、このペヌゞのすべおのナヌザヌのコヌドには、倧きくお䞍必芁な䜕かの初期化があるこずがわかりたす。 たずえば、自動展開の手段ずしお、倩気予報のWeb芁求ごずに異なるサむトに登る、たたはプロゞェクトのルヌトにある「git pull origin master」によっお実行される倧芏暡なinitメ゜ッド。 パフォヌマンス分析のプロセスでは、コヌドから単玔に砎棄するか、「ifでラップ」するこずができ、本圓に必芁な堎合にのみ必芁な郚分を含めるこずができる倚くのこずに出くわしたす。



ペヌゞの倧きなフラグメントが実質的に倉曎されないこずが非垞に䞀般的ですたずえば、ペヌゞの「ヘッダヌ」ず「フッタヌ」。 この堎合、明癜な解決策は、事前にコンテンツを生成するか、キャッシュに入れお毎回再描画しないこずです。



コヌドず実際の生掻の䞭で怠けおください。 垞に同じ䜜業を行わない誰も必芁ずしない、ナヌザヌのリク゚ストに答えるために本圓に必芁なこずのみを行い、残りは行わない、たたは誰かに委任しないたずえば、「重い」が非垞に敏感ではない遅延するためには、物事をりェブ䞊で行うのではなく、cronに委任する必芁がありたす。



4.非同期バッチ凊理を䜿甚する



さたざたなプロゞェクトで、1぀の芁求ですべおを䞀緒に凊理する代わりに、数十、数癟のレコヌドを䞀床に1぀ず぀凊理するずいう、ささいな蚭蚈゚ラヌに察応できたす。 たずえば、ペヌゞ䞊の30個の補品のデヌタを衚瀺する必芁がある堎合、「SELECT ... FROM table WHERE id = ...」ずいう圢匏の30のク゚リではなく、「SELECT ... FROM table WHERE id IN...」ずいう圢匏のク゚リを1぀䜜成したす。 ほずんどのデヌタベヌスでは、結果が30行のク゚リず結果が1行のク゚リの間に速床の違いはたったくありたせん。 原則ずしお、バッチ凊理を远加するために必芁なコヌドの倉曎は非垞に少なく、その代わりに、䜕癟回も、時には䜕癟倍も速床が向䞊したす。 これは、SQLク゚リだけでなく、倖郚たたは内郚サヌビスぞの呌び出しにも適甚されたす。 ネットワヌクに接続するず、垞にリク゚ストの凊理に倧幅な遅延が発生するため、Webの状態でリク゚ストの数を最小限に抑えるこずが非垞に望たしいです。



バッチ凊理を高速化する別の方法は非同期です。 蚀語で蚱可されおおり、異なるサヌビスぞの芁求を1぀にグルヌプ化しお非同期に実行できる堎合、応答時間も倧幅に短瞮され、サヌビスが倚いほどゲむンが倧きくなりたす。 これはMySQLにはあたり圓おはたりたせんが、たずえば䜎速のGoogle Datastore APIを䜿甚する堎合には十分に圓おはたりたす。



5.耇雑でわかりにくい混乱を単玔化する



䟋を挙げたしょう。䜕かを実行し、おそらくおそらく正しく実行するが、数癟䞇行を同時にスキャンする、かなり遅い SQLク゚リがありたす。 耇雑なSQLク゚リを最適化するには、最初に単玔化する必芁がありたす。冗長なものをすべお、堎合によっおはテヌブル党䜓たたはネストされた遞択を砎棄したす。 䞍芁なものをすべお削陀しお初めお、意味のある最適化を実行できたす。 そうしないず、無駄に倚くの時間を費やしおフラグメントを最適化できたすが、これは最終結果に圱響したせん。 倚くの堎合、特にMySQLを䜿甚する堎合、ク゚リをいく぀かの単玔なク゚リに分割したす。各ク゚リは元のク゚リよりもはるかに高速に動䜜するため、満足のいく゜リュヌションになりたす。



倚くの人々によっお開発されたシステムでは、明確で適切に蚭蚈されたコヌドの代わりに、「束葉杖を重ねる」こずがよくありたす。 これは、プログラマヌの資栌が䜎い堎合だけでなく、通垞の反埩開発でも発生したす。ただし、䞀定のリファクタリングがない堎合に限りたす。 問題がこれらの堎所のいずれかにあるこずがわかった堎合、最初にコヌドのリファクタリングを少し行う必芁がありたす。たず、その動䜜を理解し、次に、明らかに䞍芁なものをすぐに最適化たたは砎棄できたす。 単にコヌドを敎理しただけで、コヌドのパフォヌマンスが満足できるものになり、察応するフラグメントの最適化が䞍芁になるこずがよくありたす。



6.「芪愛なる」機胜



0.1のナヌザヌが䜿甚する機胜がありたすが、同時にサヌバヌでの応答時間が半分になる機胜があるこずを発芋する可胜性は十分にありたす。 その堎合、この機胜を再考しお他の「より安い」゜リュヌションを提䟛するか、この機胜をデフォルトで無効にしたす。 ナヌザヌがそれを必芁ずする堎合、圌はそれを再び぀けたす。



7.キャッシュ



他に䜕も圹に立たない堎合、たたは経時的に倉化しないデヌタがある堎合は、キャッシュしおください。 他のすべおのオプションが䜿い果たされた堎合にのみキャッシュを䜿甚する䟡倀があるず䞻匵するのはなぜですか 事実、可倉デヌタをキャッシュに入れ始めるずすぐに、キャッシュの関連性を監芖する必芁がありたすが、これは非垞に難しい゚ンゞニアリング䜜業です。



䟋䞻キヌIDでテヌブルtableに個々のレコヌドをキャッシュしたす。 1぀のレコヌド-「table_ <id>」圢匏のキャッシュ内の1぀のキヌ。 ここで、特定の条件に察しお耇数のレコヌドを曎新する必芁があるず想像しおください「テヌブルを曎新する<条件>」。 この堎合、キャッシュをフラッシュする方法は 単玔だが非垞に時間がかかる決定の1぀は、この条件を事前に遞択し、キャッシュ内のすべおの゚ントリをIDでフラッシュしおから、曎新を行うこずです。 しかし、select、キャッシュのフラッシュ、および曎新の間に、別のリク゚ストが「りェッゞ」する堎合はどうでしょうか このようなもの

最初のリク゚スト

1. <condition>のテヌブルからIDを遞択したす

2. memcacheの削陀ID







6.テヌブルセットの曎新... where <条件>

2番目の䞊列ク゚リ





3. memcache get "table_N"-空、キャッシュは既にリセットされおいたす

4. id = Nのテヌブルから...を遞択したす

5. memcache set "table_N"-叀いデヌタをキャッシュに蚭定したす




非垞にきちんず蚘述されたコヌドのない1぀ではなく2぀のデヌタ゜ヌスの存圚は、必然的にそれらの非同期化に぀ながり、キャッシュの堎合、サむト䞊の䞍敎合たたは叀いデヌタ、「壊れた」カりンタヌなどの䞍快なアヌティファクトに぀ながりたす。



もちろん、生産性を向䞊させるためにキャッシュがうたく䜿甚されおいる䟋は数倚くありたすが、ここでも他のすべおのオプションを怜蚎した埌です。 オペレヌティングシステムでは、遅いメディアでの操䜜がキャッシュされたす読み取りは単にキャッシュされ、曞き蟌みはバッファリングされ、デヌタの砎損やファむルシステム構造に぀ながるこずがありたす。 これは䜜業速床に倧きく貢献したすが、SSDずハヌドドラむブを䜿甚した堎合のナヌザヌ゚クスペリ゚ンスを比范したこずがある堎合、キャッシュにもかかわらず、埌者を再び䜿甚するこずは決しおありたせん。 サむズの異なるメモリの速床は桁違いに異なるため、プロセッサは倚くのキャッシュレベルを䜿甚したすレゞスタメモリぞのアクセス時間を玄1 ns、ハヌドディスクのアクセス時間を10ミリ秒ず比范したす-差は1000䞇倍です りィキペディアから取られたむラスト。



おわりに



そこで、䞻にPHP + MySQLバンドルを最も䞀般的なものずしお、Webアプリケヌションのパフォヌマンスを向䞊させる基本的な方法を怜蚎したした。 私は個人的に最適化のために䞊蚘のアプロヌチを䜿甚したすが、これたでのずころ、プロゞェクトを䜕回も、時には䜕十回も高速化するために倚くの努力なしで管理したした。 蚘事が最適化の方法を教えおいない堎合、少なくずもそれがあなたおよびあなたの同僚を正しい方向に抌し進め、䞖界が少し良くなるこずを願っおいたす。



*最初の図はこのペヌゞから取られおいたす Googleによる



All Articles