我正在重写一些脚本以将机器生成的日志从perl解析为php 文件范围从20mb到400mb 我遇到了这个问题,以决定是否应该使用file()或fopen()+ fgets()组合来浏览文件以获得更快的性能。
这是基本的贯穿, 我在打开它之前检查文件大小,如果文件大于100mb(非常罕见的情况,但它确实时有发生)我会去fopen + fgets路由,因为我只将脚本的内存限制提高到384mb ,任何大于100mb的文件都有可能导致致命错误。否则,我使用file()。
我只是在两种方法中逐行浏览文件一次。
这是一个问题,是否值得保持文件()部分代码来处理小文件?我不知道file()(我也使用SKIP_EMPTY_LINE选项)是如何在php中工作的,它是直接将文件映射到内存中还是在通过它时逐行扫描到内存中?我对它运行了一些基准测试,性能非常接近,40mb文件的平均差异约为0.1s,而file()在80%的时间内优于fopen + fgets(在同一文件集上的200次测试中)。
删除文件部分可以确保从系统中节省一些内存,并且考虑到我同时运行同一个脚本的3个实例,它可以在12G系统上节省我1G的内存,该系统也托管了数据库和其他垃圾。但是我不想让脚本的性能下降,因为每天有10k这样的日志进入,0.1s的差异实际上会增加。
任何建议都有帮助和TIA!
答案 0 :(得分:2)
我建议坚持使用一种机制,例如foreach(new \SplFileObject('file.log') as $line)
。拆分输入文件并并行处理,每个CPU核心2-3次。奖励:比同一系统上的数据库低优先级。在PHP中,这意味着立即产生N个副本的脚本,其中每个副本都有自己的文件列表或目录。由于您正在谈论重写和IO性能是一个问题,请考虑其他具有更多功能的平台,例如Java 7 NIO,nodejs异步IO,C#TPL。