一般测试php文件用什么,测试 PHP 几种方法写入文件的效率

测试 PHP 几种方法写入文件的效率

前置条件:

所有测试生成的都写入一个新文件, 如果时同一个文件名, 那么每次执行脚本前, 需要把该日志文件删掉, 确保每次执行时日志文件都是重新创建的.

每次执行都是往日志文件中使用多进程写入 90000 行日志. 每种方式分成四种对照组测试:

30*3000 加锁 (即 30 个进程每个进程写入 3000 行, 总共 90000 行, 写入时需对日志文件上独占锁).

30*3000 不加锁 (即 30 个进程每个进程写入 3000 行, 总共 90000 行, 写入时日志文件不上锁).

90*1000 加锁 (即 90 个进程每个进程写入 1000 行, 总共 90000 行, 写入时需对日志文件上独占锁).

90*1000 不加锁 (即 90 个进程每个进程写入 1000 行, 总共 90000 行, 写入时日志文件不上锁).

方式一:

使用 file_put_contents() 函数写入文件. 为了避免内容覆盖, 须使用 FILE_APPEND 模式写入.

加锁:(n=3000 | n=1000)for($i=0;$i

$msg="test text";

file_put_contents($log,$msg,FILE_APPEND|LOCK_EX);

}

不加锁:(n=3000 | n=1000)for($i=0;$i

$msg="test text";

file_put_contents($log,$msg,FILE_APPEND);

}

执行情况如下表:序号进程数每个进程写入行数是否加锁第一次执行平均耗时 (s)第二次执行平均耗时 (s)第三次执行平均耗时 (s)

1-1303000Y2.8312.8152.861

1-2303000N2.8262.8552.751

1-3901000Y2.4072.3962.278

1-4901000N1.7792.0522.01

方式二:

加锁:(n=3000 | n=1000)$handle=fopen($log,'a');

flock($handle,LOCK_EX);

for($i=0;$i

$msg="test text";

fwrite($handle,$msg);

}

flock($handle,LOCK_UN);

fclose($handle);

不加锁:(n=3000 | n=1000)$handle=fopen($log,'a');

for($i=0;$i

$msg="test text";

fwrite($handle,$msg);

}

fclose($handle);

执行情况如下表:序号进程数写入行数 / 每个进程是否加锁第一次执行平均耗时 (s)第二次执行平均耗时 (s)第三次执行平均耗时 (s)

2-1303000Y0.660.6590.658

2-2303000N1.2721.171.161

2-3901000Y0.830.8550.836

2-4901000N0.9521.0970.947

以方式一跟方式二的表格为参照, 同一种方式, 上不上锁, 性能相差不是很大, 从效率上讲, 方式二要比方式一高效.

最根本的原因是 file_put_contents() 函数每次执行相当于执行了 fopen(),fwrite(),fclose() 三个函数, 所以单次执行耗时会比较长.

如果把方式二做个调整, 比如把 fopen() 和 fclose 都放进 for 循环里, 那么方式二跟方式一基本没太大差别.for($i=0;$i

$handle=fopen($log,'a');

$msg="test text";

fwrite($handle,$msg);

fclose($handle);

}

不上锁的情况, 日志写进去时无序的, 各个进程之间穿插着写入日志.

上锁的情况, 日志相对有序, 基本是一个进程写完才轮到另一个进程. 但是进程之间也是无序的. 所以, 同一个进程写的日志才是有序的.<?PHP

set_time_limit(30);

$log='/data/tmp/a.log';

for($i=0;$i<30;$i++){

pcntl_signal(SIGCHLD,SIG_IGN);

$fid=pcntl_fork();

if($fid===0){

try{

$start=microtime(true);

$handle=fopen($log,'a');

flock($handle,LOCK_EX);

for($j=0;$j<3000;$j++){

$start_time=microtime(true);

//TODO 其他业务逻辑

// 打点记录并行任务执行状况

$fid=posix_getpid();

$ffid=posix_getppid();

$date=date('YmdHis');

$end_time=microtime(true);

$usetime=round($end_time-$start_time,2);

$msg=PHP_EOL."序号:{$i}:{$j}; 时间:{$date}; 当前进程 ID:{$fid}; 父进程 ID:{$ffid}; 任务开始:{$start_time}; 任务结束:{$end_time}; 耗时:{$usetime}";

//file_put_contents($log,$msg,FILE_APPEND|LOCK_EX);

fwrite($handle,$msg);

}

flock($handle,LOCK_UN);

fclose($handle);

unset($handle);

$end=microtime(true);

$s=round($end-$start,3);

echo PHP_EOL.$s.',';

//echo "进程:{$i}, 开始:{$start}, 结束:{$end}, 耗时:{$s}".PHP_EOL;

}finally{

if(function_exists("posix_kill")){

posix_kill(getmypid(),SIGTERM);

}else{

system('kill -9'.getmypid());

}

}

}

}

echo'over'.PHP_EOL;

来源: http://www.bubuko.com/infodetail-3724444.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值