遭遇php的in_array低效能的問題
PHP的性能一直在提高。然而,若是用的不恰當,或是一個不留神,還是可能會踩到PHP內部實現方面的坑的。我在前幾天的一個效能問題上就碰到了
PHP的效能一直在提升。然而,若是用的不恰當,或是一個不留神,還是可能會踩到PHP內部實現方面的坑的。我在前幾天的一個效能問題上就碰到了。
事情是這樣子的,一位同事回饋我們的一個介面每次返回需要5秒之久,我們一起review了程式碼,「驚喜」的發現居然在循環(大約900次)中調用了一個讀取快取的操作,而這個快取的key並沒有改變,因此我們把這段程式碼移到了循環外面,再測,介面返回時間降到了2秒,嗚呼!雖然提升了1倍,但明顯不是我們能接受的結果!
出現效能問題的程式碼量並不大,我們排除了IO問題以後,寫了一段測試程式碼,果然問題很快重現。
複製程式碼 程式碼如下:
<?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
對的,我們用的就是字串型的數字,從快取拿出來就是這樣子的啦!所以這裡是刻意轉成字串的(如果直接是數字,並不會出現這個問題 ,各位可以自行驗證)。可以看出時間耗掉了1秒,才3000次循環,後面的sys用時也注定我們用strace不會拿到什麼有效資訊。
shell$ strace -ttt -o xxx /usr/local/php/bin/php test.php
shell$ less xxx
我們只看到這兩次系統呼叫之間的延遲非常大,卻不知道做了什麼?一籌莫展了,幸好,Linux下的調試利器除了strace還有ltrace(當然還有dtrace,ptrace,不在本文討論範圍了,略去)。
引用:strace用來 追蹤一個進程的系統呼叫或訊號產生的情況,而 ltrace用來 追蹤進程呼叫函式庫函數的情況(via IBM developerworks)。
為了排除乾擾因素,我們將$x直接賦值為array(“0″,”1″,”2″,……)的形式,避免過多的malloc調用影響結果。執行
shell$ ltrace -c /usr/local/php/bin/php test.php
如圖2
我們看到函式庫函數__strtol_internal的呼叫非常之頻繁,達到了94%,太誇張了,然後我又查了一下這個函式庫函數__strtol_internal是乾嘛的,原來是strtol的別名,簡單的說就是把字串轉換成長整形,可以猜測PHP引擎已經偵測到這是一個字串型的數字,所以期望將他們轉換成長整型來比較,這個轉換過程中消耗了太多時間,我們再次執行:
複製程式碼 程式碼如下:
shell$ ltrace -e "__strtol_internal" /usr/local/php/bin/php test. php
可以輕鬆抓到大量下圖這樣的調用,到此,問題找到了,in_array這種鬆比較,會將兩個字元型數字字串先轉換為長整型再進行比較,卻不知性能就耗在這上面了。
知道了癥結所在,我們解決的辦法就很多了,最簡單的就是為in_array加第三個參數為true,即變為嚴格比較,同時還要比較類型,這樣避免了PHP自作聰明的轉換類型,跑起來果然快多了,程式碼如下:
複製程式碼 程式碼如下:
<?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; } } ?>
複製程式碼 程式碼如下:
shell$ time /usr/local/php/bin/php test.php
#real 0m0 .267s
user 0m0.247s
sys 0m0.020s
快了很多倍! ! !可以看到sys耗時幾乎沒有太大變化。我們再次ltrace一把,還是要把$x直接賦值,排除malloc呼叫的干擾,因為我們實際應用中是從快取裡一次拉出來的,所以也不存在範例程式碼中這樣的循環來申請記憶體的情況。
再次執行
複製程式碼 程式碼如下:
shell$ ltrace -c /usr/local/php/bin /php test.php
如下圖:
__ctype_tolower_loc佔用了最多的時間!查了一下函式庫函數__ctype_tolower_loc是幹嘛的:簡單的理解是將字串轉換成小寫,那麼這說明in_array比較字串不區分大小寫嗎?其實這個函數呼叫已經跟我們這個in_array感覺聯繫不大了,關於in_array的實現,還是去看看PHP的源碼,大概理解的更為透徹了,好了,沒法往下說了,歡迎與我交流,寫的不對的地方請多多斧正。
———————2013.08.29分割線————————
#晚上又翻了以下PHP 5.4.10的源碼,對in_array的興趣真大啊,哈哈,位於./ext/standard/array.c的第1248行,可以看到他呼叫了php_search_array函數,下面的array_serach也是調的這個,只是最後一個參數不同!經過一番跟踪,在in_array鬆比較的情況下,他最終調用的函數zendi_smart_strcmp(果然是個“聰明”函數)進行比較,位於./Zend/zend_operators.c,我們用ltrace抓到的大量轉換成整型的操作就是那個is_numeric_string_ex的行為。
函數is_numeric_string_ex是在./Zend/zend_operators.h中定義的,在前面進行了一堆的判斷和轉換之後,在232行呼叫了strtol,就是我們在文章中提到的系統函數了,將字串轉換成長整數,有圖有真相
#相關推薦:
##再度遭遇PHP對MYSQL插入中文和顯示時出現亂碼#######################################################################
以上是遭遇php的in_array低效能的問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。
