file_put_contents和fwrite对比,以及他们在高并发下问题

先说结论,单次性能,file_put_contents要比fwrite好,这个也很好理解,因为写入文件,file_put_contents就一行代码,fwrite至少三行,虽然不是说代码行少就一定快,但就这个写入功能来说,file_put_contents就等于fopen fwrite fclose,之所以前者快,就是因为一次api交互,直接干了这三件事,后者有三次api的开销。

再说问题,其实不能说是问题,应该说是一个需要注意的点,默认情况下,两者都是不是使用独占锁的方式运行,所以在高并发下,会有写入的内容被覆盖的问题。这里需要通过独占锁的方式来解决。
之前过某篇文章,对比file_put_contents和fwrite的性能,是用的循环100w次写入的方式对比,记得当时的结论是,file_put_contents用了300多秒,fwrite 10秒,那是因为,他讲fopen和fcolse放到了循环外,如果你100w拼成一个长字符,最后一次写入,那肯定更快。所以很多结论都是有特定场景的。

实验一

 <?php
    $n = "1\n";
    file_put_contents('demo1.txt',$n,FILE_APPEND);

运行代码 ab.exe -c 50 -n 100 http://local.test.com/1.php

结果,多次验证取中间结果

Time taken for tests:   0.075 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      21500 bytes
HTML transferred:       0 bytes
Requests per second:    1329.79 [#/sec] (mean)
Time per request:       37.600 [ms] (mean)
Time per request:       0.752 [ms] (mean, across all concurrent requests)
Transfer rate:          279.20 [Kbytes/sec] received

demo1.txt写入了86行,这里就出现了高并发下的问题,这里注意qps为1329

实验二、

$n = "1\n";
$fp = @fopen('demo2', 'ab');
flock($fp, LOCK_EX|LOCK_NB);
fwrite($fp, $n);
flock($fp, LOCK_UN);
fclose($fp);

结果

Time taken for tests:   0.078 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      21500 bytes
HTML transferred:       0 bytes
Requests per second:    1278.63 [#/sec] (mean)
Time per request:       39.105 [ms] (mean)
Time per request:       0.782 [ms] (mean, across all concurrent requests)
Transfer rate:          268.46 [Kbytes/sec] received

demo2写入81行,发现qps的确是比file_put_contents低一些,1278

实验三、

$n = "1\n";
file_put_contents('demo3.txt',$n,FILE_APPEND|LOCK_EX);

结果:

Time taken for tests:   0.084 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      21500 bytes
HTML transferred:       0 bytes
Requests per second:    1187.44 [#/sec] (mean)
Time per request:       42.108 [ms] (mean)
Time per request:       0.842 [ms] (mean, across all concurrent requests)
Transfer rate:          249.32 [Kbytes/sec] received

demo3.txt这次写入了100行,没有丢失,但是qps发现下降了不少1187

实验四、

$n = "1\n";
$fp = @fopen('demo4.txt', 'ab');
flock($fp, LOCK_EX);
fwrite($fp, $n);
flock($fp, LOCK_UN);
fclose($fp);

结果:

Time taken for tests:   0.095 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      21500 bytes
HTML transferred:       0 bytes
Requests per second:    1049.80 [#/sec] (mean)
Time per request:       47.628 [ms] (mean)
Time per request:       0.953 [ms] (mean, across all concurrent requests)
Transfer rate:          220.42 [Kbytes/sec] received

demo4.txt同样没有丢失,qps也是有下降。

当然了,这两个函数,和你的系统,软件版本,文件系统有很大的关系,linux下的性能明显比window要好一些。所以这里就像我上篇文章说的,web程序,和你做一个类似的批处理程序,写法是不一样,因为着重的点不一样。就是因为没有锁,所以才有好的并发效果,但是你如果一定要强制写入的完整,就需要牺牲并发的性能。

如果我们在做文件处理脚本,就适合使用颗粒度更小的函数,这样你才能在关键点,通过函数、系统逻辑特性做出优化。所以没有银弹,任何的东西都是相对的
转载请注明:http://www.521php.com/archives/2004/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一、会话控制(session与cookie) 1.cookie简介 Cookie是存储在客户端浏览器中的数据,我们...
    空谷悠阅读 3,841评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,084评论 19 139
  • 英语课,老师批改期末试卷,作文题花样百出,中式英语表现得淋漓尽致。 祝你们的公司越办越成功是“wish your ...
    蓝小鲸Crystal阅读 1,355评论 0 0
  • 小田师傅阅读 1,189评论 0 0
  • 来到上海,感觉好陌生,就像MAX老师说的一样,来到一个陌生的城市,坐着一辆陌生的车子,去到一个陌生的目的地,虽...
    杨丽娟onelife阅读 1,337评论 2 2

友情链接更多精彩内容