strtotime() は php の時間関数であり、その機能は文字列形式の日付と時刻を対応する Unix タイムスタンプに変換することです。今日は、特定の例を使用して strtotime() 関数のパフォーマンスの問題を詳細に分析します。最近、私はゲーム データ統計バックエンドに取り組んでいます。最も基本的な機能は、登録ログとログイン ログを分析してユーザー データを表示することです。社内テストではユーザー数が非常に少なかったため、パフォーマンス上の問題は見つかりませんでした。しかし、この 2 日間は実際のテスト環境に置かれ、午後から大量のユーザーが殺到し、オンラインユーザーの統計が滞り始め、クエリ速度が返されるまでに数秒かかりました。登録人数は大丈夫でした。夜になるとオンライン人口の統計が基本的にタイムアウトして開けなくなります。ゲーム側にどのようなバグがあるのかはわかりませんが、プレイヤーのログインに問題が発生することが多く、その結果、オンラインおよび登録者数が少なくなります。しかし、この少量のデータでは、クエリの速度が十分ではなく、非常に恥ずかしいことです。
現在、彼らはゲームのバグをチェックしており、私は統計の背後にあるコードのパフォーマンスも調べています。まず最初に、私が統計に使用するデータはスレーブ データベースからのものであり、彼らのゲームはメイン データベースを使用していることを説明します。また、ここには管理者が数人しかいないため、ゲーム サーバーのパフォーマンスに影響を与えることは不可能です。 。
今日、プロジェクト チームのリーダーはすべてのデータベースを会社のサーバーにインポートしました。統計プラットフォームのパフォーマンスの問題がどこにあるのかを確認するために、コピーをローカル コンピューターにコピーしました。その後、登録統計さえも非常に遅く、サーバーでは返されるまでに約 2 秒かかり、ローカル マシンでは 20 秒以上かかり、頻繁にタイムアウトになることがわかりました (PHP のデフォルト設定は 30 秒のタイムアウトです)。言うまでもなく、オンライン統計は開くことができません。データベースを調べたところ、その日の登録レコードは約 3,500 件しかありませんでした (偽のデータあり)。これらは 5 分ごとにカウントされており、これは 1 日あたり 288 回です。もちろん、これはデータベースを 288 回ループするような、死ぬほど叱られるようなクエリではありません。
期間内の登録数をカウントするロジックも非常に単純で、各期間でデータを 1 回走査し、時間サイズを比較し、一致する場合は +1 します。しかし、わずか 100 万サイクルのこのような単純なロジックに 30 分もかかるのはなぜでしょうか?
重要な問題は時間の比較にあり、タイムスタンプは時間サイズを比較するためのより科学的な方法であることは誰もが知っており、データベースに記録される時間は通常、PHP の形式で YYYY-mm-dd HH:ii:ss になります。タイムスタンプに変換する strtotime 関数があります。ただし、288 for * 3500 foreach の祝福の後、ここでの実行時間は 30 分にもなります。
$nowDayDT = strtotime( date('Y-m-d') ); $__startT = microtime(TRUE); for($i=0; $i<$allTime; $i += $gapTime){ $count = 0; //用于数据比较的 $startDT = $nowDayDT+$i; $endDT = $nowDayDT+$i+$gapTime; //用于显示的 $xAxis1 = date('H:i', $nowDayDT+$i); $xAxis2 = date('H:i', $nowDayDT+$i+$gapTime); foreach($rawData as $line){ $time = strtotime($line['log_dt']); if( $startDT<=$time && $time<$endDT ){ $count ++; } } $resArr[] = [ 'date'=>$xAxis1.'~'.$xAxis2, 'number'=>$count ]; } echo microtime(TRUE)-$__startT;
この場合、基本的にこの strtotime 関数を使用する方法はありません。では、時間を比較する他の方法は何でしょうか?答えは非常に単純ですが、PHP では 2 つの日付と時刻の文字列を直接比較できます。したがって、変更されたコードは次のようになります。すると、現在の実行時間は約 0.3 秒です
トラバーサルと再最適化
このパフォーマンスは少し心配です。内部の foreach を完全に横断するには?実際、その必要はありません。 SQL データを確認する限り、時間でソートします。最適化された時間比較アルゴリズムは次のとおりです。$__startT = microtime(TRUE); for($i=0; $i<$allTime; $i += $gapTime){ $count = 0; //用于数据比较的 $startDT = date('Y-m-d H:i:s', $nowDayDT+$i); $endDT = date('Y-m-d H:i:s', $nowDayDT+$i+$gapTime); //用于显示的 $xAxis1 = date('H:i', $nowDayDT+$i); $xAxis2 = date('H:i', $nowDayDT+$i+$gapTime); foreach($rawData as $line){ $time = $line['log_dt']; if( $startDT<=$time && $time<$endDT ){ $count ++; } } $resArr[] = [ 'date'=>$xAxis1.'~'.$xAxis2, 'number'=>$count ]; } echo microtime(TRUE)-$__startT;
関連する推奨事項:
ThinkPHPの検証コード生成・検証機能の実装方法
以上がphp_php スキルの strtotime 関数のパフォーマンス分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。