PHPのstrtotime関数の詳しい説明

怪我咯
リリース: 2023-03-13 09:22:01
オリジナル
4005 人が閲覧しました

strtotime() は、php の時間関数です。その機能は、string の形式の日付と時刻を、対応する Unix の timestamp に変換することです。今日は、特定の例を使用して 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(&#39;H:i&#39;, $nowDayDT+$i);
  $xAxis2 = date(&#39;H:i&#39;, $nowDayDT+$i+$gapTime);

  foreach($rawData as $line){
    $time = strtotime($line[&#39;log_dt&#39;]);
    if( $startDT<=$time && $time<$endDT ){
      $count ++;
    }
  }
  $resArr[] = [
    &#39;date&#39;=>$xAxis1.&#39;~&#39;.$xAxis2,
    &#39;number&#39;=>$count
  ];
}
echo microtime(TRUE)-$startT;
ログイン後にコピー

この場合、基本的にこの strtotime 関数を使用する方法はもうありません。では、時間を比較する他の方法は何でしょうか?答えは単純ですが、PHP では 2 つの日付と時刻の文字列を直接比較できます。したがって、変更されたコードは次のようになります。現在の実行時間は約 0.3 秒です

$startT = microtime(TRUE);
for($i=0; $i<$allTime; $i += $gapTime){
  $count = 0;
  //用于数据比较的
  $startDT = date(&#39;Y-m-d H:i:s&#39;, $nowDayDT+$i);
  $endDT = date(&#39;Y-m-d H:i:s&#39;, $nowDayDT+$i+$gapTime);
  //用于显示的
  $xAxis1 = date(&#39;H:i&#39;, $nowDayDT+$i);
  $xAxis2 = date(&#39;H:i&#39;, $nowDayDT+$i+$gapTime);

  foreach($rawData as $line){
    $time = $line[&#39;log_dt&#39;];
    if( $startDT<=$time && $time<$endDT ){
      $count ++;
    }
  }
  $resArr[] = [
    &#39;date&#39;=>$xAxis1.&#39;~&#39;.$xAxis2,
    &#39;number&#39;=>$count
  ];
}
echo microtime(TRUE)-$startT;
ログイン後にコピー

トラバーサルしてから最適化しました

問題が見つかるかもしれません。for 内に foreach がネストされているため、パフォーマンスが少し心配になります。foreach を完全にトラバースする必要があるかどうか。内部?実際、その必要はありません。 SQLデータを確認する限り、時間順にソートされています。最適化された時間比較アルゴリズムは次のとおりです:

for{ ...
foreach($rawData as $line){
  $time = $line[&#39;log_dt&#39;];//strtotime($line[&#39;log_dt&#39;]);
  //优化算法计算
  if($time<$startDT) continue;  //小于开始时间则跳过
  if($time>=$endDT) break;    //大于结束时间则结束
  $count ++;            //否则为符合条件
  //原始的算法
//  if( $startDT<=$time && $time<$endDT ){
//    $count ++;
//  }
}
...}
ログイン後にコピー

ここでは、 continue キーワードと Break キーワードを巧みに使用して、ループをスキップし、ループ全体を終了します。今回は、その日の最初の時間の統計では、その後のデータの大部分を直接スキップできます。最終的に、総移動時間は約 0.12 秒に短縮されました。

要約すると、大規模なデータ処理では、トラバーサル中のデータ変換を避け、複雑な原理を持つ一部の関数の使用を避ける必要があります。ストラトタイムなど

以上がPHPのstrtotime関数の詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!