吐个槽, 顺便记录.
结论: php 完败
有个项目:
1, 客户提供数据,
2, 生成新的文本
3, 将文本写入磁盘, 大概 5kb 左右
客户抱怨文件生成速度太慢了. 有时候, 需要生成上万个文件.
花了点时间, 将 2 的处理方法, 单独抽出来, 并转成 python. 分别测试...
2 这个过程, 循环 10000 次, php 和 python 花的时间都差不多, 在 35s 左右.
在这 10000 次循环里, 又加上了 3, 每次循环都会写文件. 注意,每次文件内容都是不同的.
python 在 2 的时间基础上, 多了 2, 3 秒. 试了 with open 和 f = open, f.write, f.close 两种方法, 都差不多
php 则多了 10 多秒. 试了 file_put_contents 和 fopen, fwrite, fclose....
不信邪, 研究了一晚上的 php 扩展
// php_stream *stream;
char *filename;
int filename_len = 0;
char *data;
long data_len = 0;
// long numbytes = 0;
FILE *fp;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ps", &filename, &filename_len, &data, &data_len) == FAILURE)
return;
fp = fopen(filename, "w");
fwrite(data, data_len, 1, fp);
fclose(fp);
// stream = php_stream_open_wrapper_ex(filename, "w", 0, NULL, NULL);
// numbytes = php_stream_write(stream, data, data_len);
// php_stream_close(stream);`
RETURN_LONG(data_len);
`
都这么短了, 速度能快点了吗... 直接破 50s, 现在浏览器还显示57.454752206802
无语了...
还试过 swoole 的 swoole_async_writefile, 写入文件超级快的... 只是很快 too many open files, 进程挂掉
傻逼傻逼了.....
这次都是 vagrant 里面做的测试,
这次只是纯粹测试写文件了, 10w 个文件. 文件大小 4.4kb 左右
每个脚本测试两次, 测试前先清空目录, 测试完, 统计文件数目是否 10w.秒为单位
python
result = generate_article()
a = datetime.now()
i = 100000
while (i > 0):
filename = "articles/" + str(i) + ".txt"
f = open(filename, 'w')
f.write(result)
f.close()
i = i-1
b = datetime.now()
c = b - a
php, 自写的扩展, 代码参考上面的, 别被 "mass_"名字误导了, 不是批量的意思, 这是项目的简称而已
$result = generate_article();
$a = microtime(true);
$i = 100000;
while ($i > 0) {
$filename = "articles/$i.txt";
mass_file_put_contents($filename, $result);
$i = $i - 1;
}
$b = microtime(true);
echo $b - $a;
php 的 file_get_contents
$result = generate_article();
$a = microtime(true);
$i = 100000;
while ($i > 0) {
$filename = "articles/$i.txt";
file_put_contents($filename, $result);
$i = $i - 1;
}
$b = microtime(true);
结论. php 落后一点. 扩展也不是没有帮助, 你们看下 file_put_contents 的源代码, 再和我的对比下.
在实际环境中, 需要在一个(几百次,几千,甚至上万次)循环中, 根据用户提供的数据 不断生成新文件, 并写入磁盘, 这个过程有时候很慢.
由于我们使用 redis 做队列. 于是我就琢磨着, 试下其他语言, 让它们来处理这些 io 频繁的任务.
于是就有了主题贴的乌龙测试... 还以为 php 在文件写入这块真的比不了 python.... 原来我是来 host 上的 python 和 vagrant 里的 php 对比
第一个补充贴, 纠正了这个错误, 而且是单纯的写入对比.
下图, 则是, 真实场景应用, 在循环里, 生成新文件并写入磁盘, 5000 次
php 不愧是最好的语言!!!
现在学学如何应用 pthreads 到我这个用例上... 8 核 cpu 不能浪费
1
iyaozhen 2016-03-15 23:14:43 +08:00 1
你单个目录文件写的太多了吧。 ext3 文件系统一级子目录文件数有限制( 32000 )。搞个二级目录,速度绝对能上去。
你写扩展没啥意义,底层都是 C 。 还有 swoole_async_writefile 只是异步写,还是会有一级子目录文件数的限制,以及文件系统的其它一些限制。 |
2
jhdxr 2016-03-16 00:37:21 +08:00
测试不贴代码。。。
|
3
bombless 2016-03-16 00:47:20 +08:00 via Android
试试 PHP7 吧。
其实你拿 py 出来比很不利,我们拿 rust 出来比看是你 py 的几倍(逃 (明天回公司了给你对比下 |
4
mko0okmko0 2016-03-16 01:54:49 +08:00 1
1.你没用多核心设计吃满 CPU 跟 IO 资源.
2.java 跟 C#(mono)是好东西,可以帮你搞定 1. 3.使用 swoole 看是否加上计数锁避免爆发量太大.建议(CPU 核心数+硬碟数量)x2 我不是程式语言狂热者,是遇过类似的蛋疼竞赛被坑很惨. |
5
ershisi 2016-03-16 08:45:54 +08:00
python 打开文件描述符和关闭文件描述符比较快吗?不清楚 python 的底层实现。你拿 php 扩展出来说事是没有价值的--!因为它还是封装了 c 的底层。想来应该是在封装的时候对文件描述符的判断比较多。所以在写的时候回占用一定的时间吧?
|
6
tabris17 2016-03-16 09:13:33 +08:00
你都没搞明白瓶颈在哪里
|
7
kankana OP 的确不知道瓶颈在哪里, 为毛写文件这么慢呢?
php 扩展也是我最后能想到的方法, 试试呗, 我也没搞过扩展, 失败了也权当是学习了. 对了, 用的是 php 5.6.17, 跟生产环境一样. 等等我在测试下, 现在才想到是 php 是在 vagrant 里运行, python 是在 host 上..... |
8
kankana OP `
stream = php_stream_open_wrapper_ex(filename, "w", 0, NULL, NULL); numbytes = php_stream_write(stream, data, data_len); php_stream_close(stream); ` 顺便说下, 这三行是 file_put_contents 源代码提取出来的. 我以为 php_stream*是 php 自己封装的, 用 fopen, fwrite, fclose, 会比较快点, 其实并没有.... |
9
lovedboy 2016-03-16 11:09:45 +08:00
有没有考虑过是 buffer 的原因, Python 的 IO buffer 比 php 的大?
|
10
realpg 2016-03-16 11:19:40 +08:00
不用看就知道 php 会大幅落后 python
专业的东西干专业的事儿, PHP 就是用来处理基本 web 请求的,这种东西,写个 java/c 值守程序最好, python 也可以干这个只是效率会比 java/c 低一些 |
11
BOYPT 2016-03-16 11:20:53 +08:00
基本涉及磁盘 IO 的,语言之间不应该有太大区别。
|
13
msg7086 2016-03-16 13:07:31 +08:00
写文件的时候先开 iostat 看一下写入情况。
如果是总写入速度不高,那可能是文件系统的锅,试试 reiser4 之类的黑科技。 |
14
wingoo 2016-03-16 13:51:59 +08:00
php 的读文件曾经测试过, 和 python 时间差不多
几百兆上 G 的文件 但 array 处理太慢了, 之前项目需求, 数组里大概上百万个 key, 比 python 慢了几十倍吧 |
15
situs 2016-03-16 14:23:18 +08:00
一场血雨腥风。。。
|
16
jhdxr 2016-03-16 22:40:06 +08:00
@realpg 看补充,被打脸了 233333
一个语言,如果它的执行时间差距,能比 IO 还要大(或者一个量级),那这语言得有多失败 |
18
firebroo 2016-03-17 08:46:26 +08:00 via Android
看到楼上有人被打脸,如果楼主用了 PHP7 的测试对比,估计楼上有人脸都要肿成狗了, PHP 是 web 的 c 语言,你以为真是大家随便说的-_-||
|