百度工程师对PHP函数的实现原理及性能分析(三)
计数
计数是我们经常使用的函数,它的函数是返回数组的长度。
计数函数的复杂性是什么一个常见的说法是,计数函数遍历整个数组并询问元素的数量,所以复杂性是O(n),这是实际情况吗我们回到计数看实现通过源代码可以在计数操作数组,该zif_count -> php_count_recursive ->是最后zend_hash_num_elements路径功能,zend_hash_num_elements回HT -> nnumofelements的行为,显然,这是一个O(1)O(N)操作代替实际上,数组是PHP的底部hash_table。哈希表,Zend具有特殊的元素,nnumofelements记录当前元素的数量,所以一般的计数,它实际上返回这个值。因此,我们得出的结论是,计数的复杂度为O(1),独立的特定的数组的大小。
非数组类型变量中计数的行为是什么对于非设置变量返回0,如int、双、String等将返回1。
strlen
strlen是用来返回一个字符串的长度,其实现的原理是什么我们都知道,在C语言中,函数strlen是O(n),将导线为字符串直到遇到 0,然后长出来的。它是在PHP这样的吗答案是否定的。在PHP中,字符串是由一个复合结构进行描述,包括指向特定的数据和字符串长度(类似于C++中的字符串),所以所有的直接返回字符串的长度,这是一个恒定的水平上运行。此外,对于非字符串类型的变量调用strlen,它会首先力变量被强制为字符串然后求长度,需要注意的。
建立和array_key_exists
这两个函数的最常见的用途是确定键是否存在于数组。但前者还可以用来确定变量是否已设置。如前面的文章中提到,isset是不是一个真正的功能,所以它比后者更有效。建议更换array_key_exists。
array_push和数组{ }
两者都是在数组尾部添加一个元素,不同的是前者可以不止一次推推,它们最大的区别是一个是函数,一个是语言结构,因此后者更高效,所以如果只添加元素,建议使用数组{ }。
兰德和mt_rand
两者的功能提供了一个随机数,前者使用libc标准兰德,后者利用性质Mersenne Twister称为随机数发生器。它可以生成随机值与平均速度快四倍的速度比libc(RAND)。因此,如果性能要求更高,我们可以考虑使用mt_rand代替前者。我们都知道,伦德产生一个伪随机数,而我们需要站指定的种子显示但在PHP中,兰德将默认调用你默认情况下,在一般情况下,你不需要打电话,你可以再次显示。需要注意的是,如果你需要调用srand在特殊情况下,重要的,它必须被调用。也就是说,srand兰德,到相应的mt_srand srand,不得混合使用,否则是无效的。
排序模型
两者都是用于排序,不同的是,前者可以指定排序策略,类似于我们的C和C++的qsort排序。排序,它们都是通过快速行实施标准。对于排序请求,如非特殊情况,我们可以调用PHP提供的这些方法,不需要再做一遍,因此效率要低得多,原因是比较前面文章中用户函数和内置函数的分析。
URLEncode和rawurlencode
二是URL字符串的编码,除了所有非字母数字字符- _。在将由百分号(%)取代之后两位十六进制数,两者之间的唯一区别是,对于空间的urlencode将被编码为+,和rawurlencode将被编码为% 20.in一般,除了搜索引擎,我们的策略是20.therefore空间%代码,采用后者居多。需要注意的是,编码和解码系列必须使用的重要。
系列函数strcmp
这一系列的功能包括strcmp,里,strcasecmp,和strncasecmp,和功能的C函数相同,但也有差异。由于PHP字符串允许 0出现,所以在判断的时候,它是代替strcmp memcmp系列,这是速度的理论。此外,因为PHP可以直接得到字符串的长度,它将在这一领域的第一次检查,在许多情况下,效率会更高的。
is_int和is_numeric
这两个函数的功能相似,不完全相同。要注意他们的差异时,他们used.is_int:确定一个变量的类型是整型的,PHP变量是一个专业领域的表现,因此直接确定类型,是一个绝对的O(1):is_numeric操作确定一个变量为整数或数字的字符串,这是除了整数变量将返回true,此外,字符串变量,如表1234,1E4将被判处如此。这一次是被遍历字符串。
总结和建议
总结:
通过对功能实现的原理分析和性能测试,总结出以下结论
函数调用成本为1。PHP相对较大。
2、功能相关的信息存储在一个大的hash_table。通过函数名在哈希表中搜索每个调用。因此,函数名的长度对性能有一定的影响。
3。函数返回引用没有实际意义。
4。内置的PHP函数远远高于用户函数,尤其是字符串类操作。
5。方法类、普通函数类和静态类的效率几乎相同,差别不大。
6。内置函数和相同函数的C函数的性能几乎与空函数调用的效果相同。
7。所有参数传递都是引用计数的浅拷贝,并且代价非常小。
8个数的效果。性能上的功能几乎可以忽略不计。
建议:
因此,对于PHP函数的使用,有一些建议。
1。函数可以用内置函数完成,尽可能地使用它,而不是编写PHP函数本身。
2。如果一个函数对性能要求很高,可以考虑用扩展来实现它。
3、PHP函数调用是昂贵的,所以不要对它们进行过度收费,如果你需要调用大量的代码,只需要1, 2行代码,就可以完成一些功能,建议不要封装调用。
4。不要过分迷恋各种设计模式,如上文所述,过度封装会导致性能的下降。两需求之间的权衡考虑。PHP有其自身的特点,不能太东施效颦,遵循java模式。
5。函数不应嵌套太深,递归应该谨慎。
6的表现。伪功能是非常高的,和相同的功能实现为主。例如,使用isset代替array_key_exists
7。函数返回引用不是很重要,不起实际作用,也不考虑。
8。类成员方法不比普通函数效率低,不必担心性能损失,建议考虑静态方法,可读性和安全性更好。
9。如果不是特殊需要,建议参数传递使用传递值而不是引用。当然,如果参数是一个大数组需要修改,则可以考虑参考传递。