Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP file()vs fopen()+;性能辩论_Php_Performance_File_Fopen_Fgets - Fatal编程技术网

PHP file()vs fopen()+;性能辩论

PHP file()vs fopen()+;性能辩论,php,performance,file,fopen,fgets,Php,Performance,File,Fopen,Fgets,我正在重写一些脚本,以便将机器生成的日志从perl解析为php 文件大小在20mb到400mb之间 我遇到这个问题是为了决定是否应该使用file()或fopen()+fgets()组合来浏览文件以获得更快的性能 这是基本的贯穿图, 我在打开它之前检查文件大小,如果文件大于100mb(非常罕见,但有时确实会发生),我会选择fopen+fgets路径,因为我只将脚本的内存限制提高到384mb,任何大于100mb的文件都有可能导致致命错误。否则,我使用file() 我只在这两种方法中从头到尾检查文件一

我正在重写一些脚本,以便将机器生成的日志从perl解析为php 文件大小在20mb到400mb之间 我遇到这个问题是为了决定是否应该使用file()或fopen()+fgets()组合来浏览文件以获得更快的性能

这是基本的贯穿图, 我在打开它之前检查文件大小,如果文件大于100mb(非常罕见,但有时确实会发生),我会选择fopen+fgets路径,因为我只将脚本的内存限制提高到384mb,任何大于100mb的文件都有可能导致致命错误。否则,我使用file()

我只在这两种方法中从头到尾检查文件一次,一行一行

问题是,在处理小文件的代码中保留file()部分是否值得?我不知道file()(我也使用SKIP_EMPTY_LINE选项)在php中是如何工作的,它是直接将文件映射到内存中,还是在遍历文件时逐行将其推入内存中?我在它上面运行了一些基准测试,性能非常接近,40mb文件的平均差异约为0.1s,而file()在80%的时间里优于fopen+fgets(在同一文件集上进行的200次测试中)

删除文件部分确实可以从系统中节省一些内存,考虑到我有3个相同脚本的实例同时运行,它可以在一个12G系统上为我节省1G的内存,这个12G系统也承载着数据库和其他垃圾。但是我也不想让脚本的性能下降,因为每天有大约10k的日志进入,实际上0.1秒的差异加起来


任何建议都会对你和蒂亚有帮助

我建议使用一种机制,比如
foreach(new\SplFileObject('file.log')作为$line)
。分割输入文件并并行处理,每个CPU核2-3倍。好处:优先级低于同一系统上的数据库。在PHP中,这意味着一次生成N个脚本副本,每个副本都有自己的文件列表或目录。既然你正在讨论重写和IO性能是个问题,那么考虑其他具有更高功能的平台,例如Java 7 NIO、NoDEJS异步IO、C.java TPL。< /P>你可以写一个简单的脚本来运行X倍,并在观看内存使用时输出所需的时间,然后再以另一种方式运行X次。这将使您能够了解它们在您的系统上如何处理您的数据,以及哪一个是赢家。我认为您最好编写一个实现并使其正常工作。一次读取一(或n)行文件,解释/翻译并将输出写入磁盘或w/e将适用于所有文件大小。维护另一个解决方案会增加复杂性和开发人员的时间,这总是很宝贵的。听起来,内存大小是您的限制因素,您在执行时间上还没有遇到障碍。我想给你们更多关于提高绩效的想法,但我觉得我会偏离基准;你能详细说明一下输入和输出是什么样子/需要做什么吗?输入是一个巨大的机器生成的日志,它到处都有数据,并且不是统一的行格式,我需要从中解析不同的数据。因此,更详细地说,对于每种类型的数据,它都有自己的类/对象来跟踪其所处的阶段,并且一旦形成了完整的数据行,将其转储到csv文件中,稍后将批量上载到数据库。内存本身,如果我能获得显著的性能提升,我不介意抛出1Gb。但基准测试与php相差微秒。就执行时间而言,我有点接近它。而跳转到记忆路线似乎不会让我远离那个边缘。在perl中,将文件读入内存和处理过去很快,但由于数据变得越来越复杂,我需要对象支持来维护干净的代码,而且我对perl一点也不擅长,因此切换到php。我想我的问题更多的是关于php中的file()如何将文件映射到内存中,如果它从头到尾只经过一次,我想答案很清楚,我应该放弃这个想法:对最后一条评论进行x更正。file()在80%的时间内具有~.1s的优势,否则将落后.2~3s