常用的php函數(shù)的實(shí)現(xiàn)和介紹
常用php函數(shù)實(shí)現(xiàn)及介紹
count
count是我們經(jīng)常用到的一個(gè)函數(shù),其功能是返回一個(gè)數(shù)組的長(zhǎng)度。
count這個(gè)函數(shù),其復(fù)雜度是多少呢? 一種常見的說法是count函數(shù)會(huì)遍歷整個(gè)數(shù)組然后求出元素個(gè)數(shù),因此復(fù)雜度是O(n)。那實(shí)際情況是不是這樣呢?我們回到count的實(shí)現(xiàn)來看一下,通過源碼可以發(fā)現(xiàn),對(duì)于數(shù)組的count操作,
函數(shù)最終的路徑是zif_count-> php_count_recursive-> zend_hash_num_elements,而zend_hash_num_elements的行為是 return ht->nNumOfElements,
可見,這是一個(gè)O(1)而不是O(n)的操作。實(shí)際上,數(shù)組在php底層就是一個(gè)hash_table,對(duì)于hash表,zend中專門有一個(gè)元素nNumOfElements記錄了當(dāng)前元素的個(gè)數(shù),因此對(duì)于一般的count實(shí)際上直接就返回了這個(gè)值。由此,我們得出結(jié)論: count是O(1)的復(fù)雜度,和具體數(shù)組的大小無關(guān)。
非數(shù)組類型的變量,count的行為時(shí)怎樣?對(duì)于未設(shè)置變量返回0,而像int、double、string等則會(huì)返回1
strlen
Strlen用于返回一個(gè)字符串的長(zhǎng)度。那么,他的實(shí)現(xiàn)原理是如何的呢?我們都知道在c中strlen是一個(gè)o(n)的函數(shù),會(huì)順序遍歷字符串直到遇到,然后出長(zhǎng)度。Php中是否也這樣呢?答案是否定的,php里字符串是用一個(gè)復(fù)合結(jié)構(gòu)來描述,
包括指向具體數(shù)據(jù)的指針和字符串長(zhǎng)度(和c++中string類似),因此 strlen就直接返回字符串長(zhǎng)度了,是常數(shù)級(jí)別的操作。另外,對(duì)于非字符串類型的變量調(diào)用strlen,它會(huì)首先將變量強(qiáng)制轉(zhuǎn)換為字符串再求長(zhǎng)度,這點(diǎn)需要注意。
isset和array_key_exists
這兩個(gè)函數(shù)最常見的用法都是判斷一個(gè) key是否在數(shù)組中存在。但是前者還可以用于判斷一個(gè)變量是否被設(shè)置過。如前文所述,isset并非真正的函數(shù),因此它的效率會(huì)比后者高很多。推薦用它代替array_key_exists。
array_push和array[]
兩者都是往數(shù)組尾部追加一個(gè)元素。不同的是前者可以一次push多個(gè)。他們最大的'區(qū)別在于一個(gè)是函數(shù)一個(gè)是語言結(jié)構(gòu),因此后者效率要更高。因此如果只是普通的追加元素,建議使用array []。
rand和mt_rand
兩者都是提供產(chǎn)生隨機(jī)數(shù)的功能,前者使用 libc標(biāo)準(zhǔn)的rand。后者用了 Mersenne Twister 中已知的特性作為隨機(jī)數(shù)發(fā)生器,它可以產(chǎn)生隨機(jī)數(shù)值的平均速度比 libc 提供的 rand() 快四倍。因此如果對(duì)性能要求較高,可以考慮用mt_rand代替前者。
我們都知道,rand產(chǎn)生的是偽隨機(jī)數(shù),在C中需要用srand顯示指定種子。但是在php中,rand會(huì)自己幫你默認(rèn)調(diào)用一次srand,一般情況下不需要自己再顯示的調(diào)用。需要注意的是,如果特殊情況下需要調(diào)用srand時(shí),一定要配套調(diào)用。
就是說srand對(duì)于rand,mt_srand對(duì)應(yīng)srand,切不可混合使用,否則是無效的。
sort和 usort
兩者都是用于排序,不同的是前者可以指定排序策略,類似我們C里面的qsort和C++的sort。在排序上兩者都是采用標(biāo)準(zhǔn)的快排來實(shí)現(xiàn),對(duì)于有排序需求的,如非特殊情況調(diào)用php提供的這些方法就可以了,不用自己重新實(shí)現(xiàn)一遍,
效率會(huì)低很多。原因見前文對(duì)于用戶函數(shù)和內(nèi)置函數(shù)的分析比對(duì)。
urlencode和rawurlencode
這兩個(gè)都是用于 url編碼, 字符串中除了 -_. 之外的所有非字母數(shù)字字符都將被替換成百分號(hào)(%)后跟兩位十六進(jìn)制數(shù)。兩者唯一的區(qū)別在于對(duì)于空格,urlencode會(huì)編碼為+,而 rawurlencode會(huì)編碼為。
一般情況下除了搜索引擎,我們的策略都是空格編碼為。因此采用后者的居多。注意的是encode和 decode系列一定要配套使用。
strcmp系列函數(shù)
這一系列的函數(shù)包括strcmp、 strncmp、strcasecmp、strncasecmp,實(shí)現(xiàn)功能和C函數(shù)相同。但也有不同,由于php的字符串是允許出現(xiàn),因此在判斷的時(shí)候底層使用的是memcmp系列而非strcmp,
理論上來說更快。另外由于php直接能獲取到字符串長(zhǎng)度,因此會(huì)首先這方面的檢查,很多情況下效率就會(huì)高很多了。
is_int和is_numeric
這兩個(gè)函數(shù)功能相似又不完全相同,使用的時(shí)候一定需要注意他們的區(qū)別。Is_int:判斷一個(gè)變量類型是否是整數(shù)型,php變量中專門有一個(gè)字段表征類型,因此直接判斷這個(gè)類型即可,
是一個(gè)絕對(duì) O(1)的操作 Is_numeric:判斷一個(gè)變量是否是整數(shù)或數(shù)字字符串,也就是說除了整數(shù)型變量會(huì)返回true之外,對(duì)于字符串變量,如果形如”1234”,”1e4”等也會(huì)被判為true。這個(gè)時(shí)候會(huì)遍歷字符串進(jìn)行判斷。
總結(jié)及建議
總結(jié):
通過對(duì)函數(shù)實(shí)現(xiàn)的原理分析和性能測(cè)試,我們總結(jié)出以下一些結(jié)論
1. Php的函數(shù)調(diào)用開銷相對(duì)較大。
2. 函數(shù)相關(guān)信息保存在一個(gè)大的hash_table中,每次調(diào)用時(shí)通過函數(shù)名在hash表中查找,因此函數(shù)名長(zhǎng)度對(duì)性能也有一定影響。
3. 函數(shù)返回引用沒有實(shí)際意義
4. 內(nèi)置php函數(shù)性能比用戶函數(shù)高很多,尤其對(duì)于字符串類操作。
5. 類方法、普通函數(shù)、靜態(tài)方法效率幾乎相同,沒有太大差異
6. 除去空函數(shù)調(diào)用的影響,內(nèi)置函數(shù)和同樣功能的C函數(shù)性能基本差不多。
7. 所有的參數(shù)傳遞都是采用引用計(jì)數(shù)的淺拷貝,代價(jià)很小。
8. 函數(shù)個(gè)數(shù)對(duì)性能影響幾乎可以忽略
建議:
因此,對(duì)于php函數(shù)的使用,有如下一些建議
1. 一個(gè)功能可以用內(nèi)置函數(shù)完成,盡量使用它而不是自己編寫php函數(shù)。
2. 如果某個(gè)功能對(duì)性能要求很高,可以考慮用擴(kuò)展來實(shí)現(xiàn)。
3. Php函數(shù)調(diào)用開銷較大,因此不要過分封裝。有些功能,如果需要調(diào)用的次數(shù)很多本身又只用1、2行代碼就行實(shí)現(xiàn)的,建議就不要封裝調(diào)用了。
4. 不要過分迷戀各種設(shè)計(jì)模式,如上一條描述,過分的封裝會(huì)帶來性能的下降。需要考慮兩者的權(quán)衡。Php有自己的特點(diǎn),切不可東施效顰,過分效仿java的模式。
5. 函數(shù)不宜嵌套過深,遞歸使用要謹(jǐn)慎。
6. 偽函數(shù)性能很高,同等功能實(shí)現(xiàn)下優(yōu)先考慮。比如用isset代替array_key_exists
7. 函數(shù)返回引用沒有太大意義,也起不到實(shí)際作用,建議不予考慮。
8. 類成員方法效率不比普通函數(shù)低,因此不用擔(dān)心性能損耗。建議多考慮靜態(tài)方法,可讀性及安全性都更好。
9. 如不是特殊需要,參數(shù)傳遞都建議使用傳值而不是傳引用。當(dāng)然,如果參數(shù)是很大的數(shù)組且需要修改時(shí)可以考慮引用傳遞。
【常用的php函數(shù)的實(shí)現(xiàn)和介紹】相關(guān)文章:
1.關(guān)于php常用的系統(tǒng)函數(shù)
3.探討PHP函數(shù)的實(shí)現(xiàn)原理及性能
4.PHP實(shí)現(xiàn)數(shù)字補(bǔ)零功能的2個(gè)函數(shù)詳細(xì)介紹