事情是這樣子的,一位同事反饋我們的一個(gè)接口每次返回需要5秒之久,我們一起revi " /> 日本一卡二卡三卡四卡无卡免费播放,亚洲欧美国产综合在线,沈芯语麻豆0076 视频

天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

遭遇php的in_array低性能問題

php的性能一直在提高。然而,若是用的不恰當(dāng),或是一個(gè)不留神,還是可能會(huì)踩到php內(nèi)部實(shí)現(xiàn)方面的坑的。我在前幾天的一個(gè)性能問題上就碰到了。

事情是這樣子的,一位同事反饋我們的一個(gè)接口每次返回需要5秒之久,我們一起review了代碼,“驚喜”的發(fā)現(xiàn)居然在循環(huán)(大約900次)中調(diào)用了一個(gè)讀緩存的操作,而這個(gè)緩存的key并沒有改變,因此我們把這段代碼移到了循環(huán)外面,再測(cè),接口返回時(shí)間降到了2秒,嗚呼!雖然提升了1倍,但明顯不是我們能接受的結(jié)果!
出現(xiàn)性能問題的代碼量并不大,我們排除了IO問題以后,寫了一段測(cè)試代碼,果然問題很快重現(xiàn)。

復(fù)制代碼 代碼如下:
<?php
$y="1800";
$x = array();
for($j=0;$j<2000;$j++){
$x[]= "{$j}";
}

for($i=0;$i<3000;$i++){
if(in_array($y,$x)){
continue;
}
}
?>


shell$ time /usr/local/php/bin/php test.php

real 0m1.132s
user 0m1.118s
sys 0m0.015s

對(duì)的,我們用的就是字符串型的數(shù)字,從緩存拿出來就是這樣子的啦!所以這里是特意轉(zhuǎn)成字符串的(如果直接是數(shù)字,并不會(huì)出現(xiàn)這個(gè)問題 ,各位可以自行驗(yàn)證)。可以看出時(shí)間耗掉了1秒,才3000次循環(huán),后面的sys用時(shí)也注定我們用strace不會(huì)拿到什么有效信息。

shell$ strace -ttt -o xxx /usr/local/php/bin/php test.php
shell$ less xxx

in_array.strace

我們只看到這兩次系統(tǒng)調(diào)用之間的延時(shí)非常大,卻并不知道干了什么?一籌莫展了,幸好,Linux下的調(diào)試?yán)鞒藄trace還有l(wèi)trace(當(dāng)然還有dtrace,ptrace,不在本文討論范圍了,略去)。

引用:strace用來 跟蹤一個(gè)進(jìn)程的系統(tǒng)調(diào)用或信號(hào)產(chǎn)生的情況,而 ltrace用來 跟蹤進(jìn)程調(diào)用庫函數(shù)的情況(via IBM developerworks)。

為了排除干擾因素,我們將$x直接賦值為array(“0″,”1″,”2″,……)的形式,避免過多的malloc調(diào)用影響結(jié)果。執(zhí)行

shell$ ltrace -c /usr/local/php/bin/php test.php

如圖2

in_array.ltrace1


我們看到庫函數(shù)__strtol_internal的調(diào)用非常之頻繁,達(dá)到了94%,太夸張了,然后我又查了一下這個(gè)庫函數(shù)__strtol_internal是干嘛的,原來是strtol的別名,簡(jiǎn)單的說就是把字符串轉(zhuǎn)換成長(zhǎng)整形,可以猜測(cè)php引擎已經(jīng)檢測(cè)到這是一個(gè)字符串型的數(shù)字,所以期望將他們轉(zhuǎn)換成長(zhǎng)整型來比較,這個(gè)轉(zhuǎn)換過程中消耗了太多時(shí)間,我們?cè)俅螆?zhí)行:

復(fù)制代碼 代碼如下:
shell$ ltrace -e "__strtol_internal" /usr/local/php/bin/php test.php


可以輕松抓到大量下圖這樣的調(diào)用,到此,問題找到了,in_array這種松比較,會(huì)將兩個(gè)字符型數(shù)字串先轉(zhuǎn)換為長(zhǎng)整型再進(jìn)行比較,卻不知性能就耗在這上面了。

tu3

知道了癥結(jié)所在,我們解決的辦法就很多了,最簡(jiǎn)單的就是為in_array加第三個(gè)參數(shù)為true,即變?yōu)閲?yán)格比較,同時(shí)還要比較類型,這樣避免了php自作聰明的轉(zhuǎn)換類型,跑起來果然快多了,代碼如下:

復(fù)制代碼 代碼如下:
<?php
$y="1800";
$x = array();
for($j=0;$j<2000;$j++){
        $x[]= "{$j}";
}

for($i=0;$i<3000;$i++){
        if(in_array($y,$x,true)){
                continue;
        }
}
?>

復(fù)制代碼 代碼如下:
shell$ time /usr/local/php/bin/php test.php

real 0m0.267s
user 0m0.247s
sys 0m0.020s


快了好多倍啊!!!可以看到sys耗時(shí)幾乎沒有太大變化。我們?cè)俅蝜trace一把,還是要把$x直接賦值,排除malloc調(diào)用的干擾,因?yàn)槲覀儗?shí)際應(yīng)用中是從緩存里一次拉出來的,所以也不存在示例代碼中這樣的循環(huán)來申請(qǐng)內(nèi)存的情況。
再次執(zhí)行

復(fù)制代碼 代碼如下:
shell$ ltrace -c /usr/local/php/bin/php test.php


如下圖:

in_array.ltrace2

__ctype_tolower_loc占用了最多的時(shí)間!查了一下庫函數(shù)__ctype_tolower_loc是干嘛的:簡(jiǎn)單的理解是將字符串轉(zhuǎn)換成小寫,那么這說明in_array比較字符串不區(qū)分大小寫嗎?其實(shí)這個(gè)函數(shù)調(diào)用已經(jīng)和我們這個(gè)in_array感覺聯(lián)系不大了,關(guān)于in_array的實(shí)現(xiàn),還是去看看php的源碼,大概理解的更為透徹了,好了,沒法往下說了,歡迎與我交流,寫的不對(duì)的地方請(qǐng)多多斧正。

―――――――2013.08.29分割線――――――――――

晚上又翻了以下php 5.4.10的源碼,對(duì)in_array的興趣真大啊,哈哈,位于./ext/standard/array.c的第1248行,可以看到他調(diào)用了php_search_array函數(shù),下面的array_serach也是調(diào)的這個(gè),只是最后一個(gè)參數(shù)不同!經(jīng)過一番跟蹤,在in_array松比較的情況下,他最終調(diào)用的函數(shù) zendi_smart_strcmp(果然是個(gè)“聰明”函數(shù))進(jìn)行比較,位于./Zend/zend_operators.c,我們用ltrace抓到的大量轉(zhuǎn)換成整型的操作就是那個(gè)is_numeric_string_ex的行為。

%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-08-29-23.13.20

函數(shù)is_numeric_string_ex是在./Zend/zend_operators.h中定義的,在前面進(jìn)行了一堆的判斷和轉(zhuǎn)換之后,在232行調(diào)用了strtol,就是我們?cè)谖恼轮刑岬降南到y(tǒng)函數(shù)了,將字符串轉(zhuǎn)換成長(zhǎng)整型,有圖有真相

zend_operators-is_num

php技術(shù)遭遇php的in_array低性能問題,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 男女啪啪抽搐呻吟高潮动态图 | 日本十八禁无遮拦啪啪漫画 | 国产精品成人网 | 99久久精品毛片免费播放 | 亚洲人人为我我为人人 | 国内精品欧美久久精品 | 国产视频a在线观看v | 狠狠色狠狠色综合日日92 | 妻子+免费观看完整 | 久久国产免费观看精品1 | 麻美ゆま夫の目の前で犯 | 久久成人国产精品一区二区 | 无码欧美XXXXX在线观看裸 | 亚洲免费久久 | 国产乱码伦人偷精品视频 | 久久久久久久久性潮 | 高h乱一受多攻男男 | 麻豆成人AV久久无码精品 | 97 sese| 国产伦子沙发午休系列资源曝光 | 免费亚洲视频在线观看 | 欧美人成人亚洲专区中文字幕 | 曰产无码久久久久久精品 | 国产区在线不卡视频观看 | 99久久精品免费精品国产 | 67194con免费福和视频 | 久久国产精品无码视欧美 | 午夜向日葵视频在线观看 | 国产综合无码一区二区色蜜蜜 | 日本xxx护士与黑人 日本xxxx裸体xxxx | 无套内射无矿码免费看黄 | 国产精品无码久久av | JAVASCRIPTJAVA水多多 | 视频一区视频二区ae86 | 免费看片A级毛片免费看 | 国产免费久久爱久久啪 | 亚洲 欧美 制服 视频二区 | 国产精自产拍久久久久久蜜 | MD传媒在线观看佳片 | 亚洲欧美韩国综合色 | 国产精品免费视频播放 |