成人精品一区二区三区中文字幕-成人精品一区二区三区-成人精品一级毛片-成人精品亚洲-日本在线视频一区二区-日本在线视频免费

導航首頁 ? 技術教程 ? php中strtotime函數性能分析
全站頭部文字 我要出現在這里
php中strtotime函數性能分析 751 2024-01-10   

最近在做一個游戲數據統計后臺,最基礎的功能是通過分析注冊登錄日志來展示用戶數據。在公司內部測試,用戶量很少,所以就沒有發現什么性能問題。但是這兩天一起放到真實的測試環境,用戶量噌噌地就涌進來了,從下午開始,在線人數的統計開始卡,幾秒鐘才返回數據;注冊人數的查詢速度還行。到了晚上,在線人數的統計基本上就加載超時打不開了。雖然不知他們游戲端那邊什么BUG,玩家那邊登錄經常出問題,導致在線人數和注冊人數并不是很多。但是就這一點數據量我這邊查詢的速度也不行,這就很尷尬了。

現在他們那邊在查游戲的BUG,我這邊也在看統計后臺的代碼到底性能出在哪里。首先說明一下,我統計用的數據是從庫,他們游戲用的是主庫,再說我這邊管理員人數就幾個,不可能會影響到游戲服的性能問題。

今天項目組長把數據庫都導過來到公司內的服務器。我拷了一份到本機,看看統計平臺的性能問題出在哪里。然后卻發現,居然連注冊統計都非常卡,服務器上是兩秒左右返回,本機要二十幾秒,還經常超時(PHP的默認配置是30秒超時);在線統計的就不用說了肯定打不開。看了一下數據庫,當天的注冊記錄也就 3500 條左右(有假數據),每五分鐘統計一次,一天就是統計 288 次。當然這里肯定不是循環查詢數據庫288次,那樣會被罵死的吧。

統計時間段內的注冊數,邏輯也非常簡單,就是每個時間段遍歷一次數據,比較時間大小,符合就+1。但是為什么這么簡單的邏輯,也就一百萬次循環,怎么會跑出了足足半分鐘的時間那么久呢?

關鍵問題就出在于 時間比較這里了,我們都知道,時間戳是比較時間大小的一個比較科學的方法,而數據庫里記錄的時間一般都是以 YYYY-mm-dd HH:ii:ss 的形式,PHP里有strtotime的函數轉換成時間戳。然而在288個for * 3500個foreach 的加持之后,這里的執行時間長達半分鐘。

$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里面可以直接比較兩個日期時間字符串!所以改過后的代碼如下。然后現在的運行時間大概是 0.3秒

$__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;

遍歷再優化

大家可能發現一個問題,for 里面嵌套一個 foreach,這性能有點擔憂,其中里面的 foreach 有必要完全遍歷嗎?其實是不必的。只要查SQL數據的時候,按時間排序排出來。優化后的時間比較算法如下:

for{ ...
foreach($rawData as $line){
  $time = $line['log_dt'];//strtotime($line['log_dt']);
  //優化算法計算
  if($time<$startDT) continue;  //小于開始時間則跳過
  if($time>=$endDT) break;    //大于結束時間則結束
  $count ++;            //否則為符合條件
  //原始的算法
//  if( $startDT<=$time && $time<$endDT ){
//    $count ++;
//  }
}
...}

這里巧用了 continue 和 break 關鍵字,用于跳過一次循環和結束整個循環。這次的話,一天中剛開始的時間統計中,后面很大一部分數據的都可以直接跳過。最后總遍歷時間縮短為約0.12秒 。

總結,在大型的數據處理中,應該盡量避免在遍歷中進行數據的轉換,避免用一些原理復雜的函數。如strtotime



主站蜘蛛池模板: 一点歌词完整版| 金三角电影| 纵横欲海| 欠条怎么写才有法律效果| 我是老师电影完整版| 容易失禁的女仆桃乃木香奈| 铁血使命演员表全部| 二年级最佳家长评语| 淮剧赵五娘| 男微信头像| 追踪 电影| 麻豆视频观看| 爱在记忆中找你歌词| 李安娜| 手机抖音网页版入口| 方谬神探结局细思极恐| 最美表演| 小小少年电影简介| 生气的形容词| 女同版痴汉电车| 澳门风云2演员表| 手机忘记开机密码了怎么解开| 水管十大品牌排行榜前十名| 电影不知不觉诱惑你| 卜冠今| 金靖演过的电视剧有哪些| gay movies| 失魂家族| 情人看刀| 太深了太爽了受不了了| 长元音| 毒鲨| 质量教育培训的首要内容是() (单选题)| 台湾早期经典怀旧内衣模特走秀| 电子请柬结婚模板免费| 王者荣耀电视剧| 烽火硝烟里的青春演员表| 在线播放网站| 菊地亚美| 林心如演过的电视剧大全| 50000蛋币兑换码2025年有效|

!!!站長長期在線接!!!

網站、小程序:定制開發/二次開發/仿制開發等

各種疑難雜癥解決/定制接口/定制采集等

站長微信:lxwl520520

站長QQ:1737366103