PHP 5.2.0 有点不可理喻

转载

最近两周快被搞疯了,没想到一个简单分析日志的小脚本被搞的这么复杂。

脚本是这样,每天从各个 web 服务器上抓取 apache log,约 8 - 10G,然后分析,并生成海量的 html(20K+ 个),约 3G+(求和需要很长时间,很少去算),数量上讲有点变态,但对于我这个需求来讲是合适的,我只需要保存大约 10 天的数量,再久的就可以打包了,打包后才 60MB/天。

在我自己机器上,一切都调配好了,于是放到了一台 FreeBSD 的机器上,发现随着文件数量急剧增加,创建新文件的速度直线下降,怀疑是 ext3 过于智能的减少文件碎片的算法所导致的,不过没时间研究问题所在了。直接重装成 win XP + NTFS,莫名其妙的问题又出现了——我那个脚本分析 60MB 数据需要约 14 秒,但是在新机器上怎么跑都是 39 秒,这意味着我原本计划每天 8 个小时能跑完的脚本可能 24 小时都跑不完。于是我毫无头绪的开始检查分区规划是否有问题、簇的大小、IDE 数据线是不是 ATA100 的、除了 Intel INF 还得装点什么驱动之类各种各样能想得到的点,但都不是

网管给我了一个叫 HD Tune 的软件让我确认,这台新机器装的跟我自己的机器一样健康,磁盘读写的测试结果几乎一模一样。最后我能找的到的区别是,我自己机器上的 PHP 是 5.1.6,而新机器我装的是 5.2.0

我把 PHP 目录换掉,php5ts.dll 覆盖掉,于是,新机器上跑起来也是 14 秒了。

我一直以为 fgets 是最底层的操作,比方说 PHP 里写一个文件应该在 shell 下用管道符生成一个文件的速度应该是非常接近的,瓶颈应该在磁盘 IO 上,但是我错了

我那个脚本主要就是这么个基本的循环读取每行数据的

$fileHandle = fopen($sFileName, "r")
while (!feof($fileHandle)) {
	$sLine = fgets($fileHandle);
	...

从现在的表面现象上看,相同读日志脚本在 5.1.6 跟 5.2.0 上效率差了两倍半,原因么……

A. 最近的 php 很多 fix,以至于连 fgets 这么古老的函数都受影响

B. 跟 fgets 没关系,我读取数据后将各种信息放到一个超大数组里,由于更 oo 的新版在某些内存分配、指针或者什么 ooxx 的不为人知的改动导致对这个大数组的操作变的缓慢(更不太可能,内存再慢也差不出 25 秒啊)

没有时间测试/分析具体原因了,只要这个脚本正常运行了就好(巧合编程?随鸭去吧)以及之前所说的怀疑 ext3 格式无法胜任这种写文件的方式,也只是猜测

任务缓存早已溢出,赶紧下一任务吧