-
关于PHP性能的那些事
发表于 2010年08月5日 3 条评论PHP之父Rasmus Lerdorf昨日刚发布了一个叫做《PHP Performance》的Online PPT,深入浅出,简单直白,以WordPress为例详细解说了优化的方法和相关的工具(strace, Callgrind, Xdebug, xhprof等),最后总结中有两点让我深有同感:一是说性能实际上是灵活性和成本之间的权衡取舍,另外一个则是真正的去看待性能问题,应该是面向架构(Real performance is architecture-driven)。
我自己用过好几种编程语言进行企业项目开发,一直以为,对语言的选择应该基于应用场景和业务需求等,与是不是真的OO,性能高不高,代码结构是不是够敏捷等其实没有太多关系。比如频繁更新页面的推广活动,那自然是PHP/ASP之流合适,电子商务等需要事务、安全、稳定的Web应用使用Java,有较多自定义行为(略有差异于系统自身实现)的桌面应用使用VC等等。 而语言的性能差异,往往并不是我们所需要去关心的。 印度人做项目时满足用户性能指标的方式往往是告诉用户什么配置的机器能达到这个指标。这是因为重构算法让代码的性能翻倍往往远不如将CPU换成多核,内存加个几G来得简单、快捷和廉价。
应该说,PHP从性能上来说是有一些先天劣势的(事实上PHP在语言性能排行榜当中确实不太靠前),每次运行必须重新编译就是一个巨大的成本,从Rasmus的第一个优化就是安装APC就可以看出来这一点。嗯,是的,十分庆幸,我们有APC、eAccelerator、XCache等优秀的op-code缓存帮助我们解决了这个PHP最大的性能问题。紧跟其后的一个重要性能问题是由OOP引入的,事实上PHP 5直到PHP 5.2才得到了广泛的应用,因为PHP 5.2在面向对象的开发方面性能大为提高,已经逼近了函数式编程的性能水准。但时至今日,也依然有一些性能障碍难以解决,比如说由于动态语言的特性,PHP即使有op-code cache,也需要在每次请求的时候重新建立常量列表、可调用函数列表、可调用类列表。 这对于大型企业项目来说,简直是个噩梦。而PHP变量对内存利用的低下也是一个进行大数据量处理时会碰到的严肃问题,资深的PHPer能通过pack指令来解决它,但这真的很不优雅,充满着无奈。(你知道一个100万个数字的数组在PHP中占用多少个字节吗?如果是同样数据量的二维数组呢? 查过这个数字的Java程序员和C/C++程序员都用一种怜悯的眼神看着PHPer)
但,世界上最大的SNS网站,正在挑战Google的Facebook正是用的PHP!而他们能用PHP做到这样的规模,恰恰就是和“Real performance is architecture-driven”相互呼应的“Languages's don't Scale, Architecture Scale”。所以说,“PHP is rarely the bottleneck”,性能的关键在于,你的项目是怎么架构的。
相关日志:
PHP/JS/Shell php, 性能, 架构
-
也说海量数据的快速排序
发表于 2010年07月11日 没有评论年初的时候就有同事面完以后回来和我聊过,5000万无重复32位无符号整数中取出10000个数字的时间+空间最优排序方法,以及存在重复数字时的最优方法。 今天正好有空,把当时考虑的解决思路写下来:
首先肯定是空间换时间,方法基于位运算创建一个大内存区,单次接受数据,每个数字设置其所属的bit,随后遍历输出。这样子的话所需要的内存空间是32-3=29位,也就是512M。这个算法时间性能是足够保证了,毕竟无迭代,空间通过分块的方式来降低是一个思路,但4亿数据(32位)中有5000万,稀疏的程度远不足够,只能作罢。 这个方案的好处是即使进行全排序,其时间性能和空间性能也不会发生改变。 空间最优则应该是通过维护一个红黑树,先丢10000个数字进去,然后遍历剩下的数,从红黑树中汰选最小值替换之即可,遍历红黑树进行汰选前先比较预存的树中最小数在正常分布下能有效减少性能损失。
重复数字的简单解决方法是增加一次遍历,首次遍历将需要取出的10000个数字汇总后构建哈希表,再次遍历时仅只计算哈希表中元素的出现次数,最后按照10000个数字的次序遍历,并累计哈希表中的计数至10000次即可。 空间最优方案依然还是选择红黑树。
从综合考虑上来说当然是红黑树的实现在时间和空间上都有不俗的表现,但实际应用起来还是位运算靠谱,毕竟再怎么高效查找也好,碰上一个悲观分布(数据本来就是有序的且和要求输出序同向),那就是5000万次树遍历了。而位运算的空间占用是恒定的,时间则和总数据量等比,非常稳定。
当然,如果是有重复,全排序,基本上也只能考虑MapReduce了。
相关日志:



最近评论