PHP fwrite and file_put_contents performance comparison test

First, let's make a conclusion: PHP program will not keep a lot of log records. Generally speaking, the PHP program encounters an exception, outputs a file log, and then ends. In this case, how should I choose? In fact, it is obvious from the result of strace, the result of fwrite and file_put_contents system call is the same, and the file_put_contents call is simple, and it is a php call, which can save function variable transfer. Therefore, in general, using file_put_contents is a good choice.

1. Performance test

As with most articles, start with the performance method:

<?php
$start_time = microtime(true);
$fp = fopen("fwrite.txt","w");
for ($i = 1;$i <= 1000000;++$i) {
    fwrite($fp, "{$i}\r\n");
}
fclose($fp);
$end_time = microtime(true);
echo "fwrite cost:",($end_time-$start_time),"\r\n";
 
$start_time = microtime(true);
for ($i = 1;$i <= 1000000;++$i) {
file_put_contents("file_put_contents.txt","{$i}\r\n",FILE_APPEND);
}
$end_time = microtime(true);
echo "file_put_contents cost:",($end_time-$start_time),"\r\n";

Result output:

fwrite cost:46.916671991348
file_put_contents cost:437.18376493454

Put fopen and fwrite into a loop:

<?php
$start_time = microtime(true);

for ($i = 1;$i <= 1000000;++$i) {
    $fp = fopen("fwrite.txt","w");
    fwrite($fp, "{$i}\r\n");
    fclose($fp);
}

$end_time = microtime(true);
echo "fwrite cost:",($end_time-$start_time),"\r\n";
 
$start_time = microtime(true);
for ($i = 1;$i <= 1000000;++$i) {
file_put_contents("file_put_contents.txt","{$i}\r\n",FILE_APPEND);
}
$end_time = microtime(true);
echo "file_put_contents cost:",($end_time-$start_time),"\r\n";

Result output:

fwrite cost:851.75481009483

file_put_contents cost:451.74156188965

It can be seen that the performance difference between fwrite and file_put_contents is most reflected in the position of fopen and fclose.

 

Two, strace analysis

Let's use strace to analyze why fwrite is faster. Simply modify the PHP script. The $i condition in the for loop is changed to less than or equal to 2, which means it will be executed twice.

<?php
$start_time = microtime(true);
$fp = fopen("fwrite.txt","w");
for ($i = 1;$i <= 2; ++$i) {
    fwrite($fp, "{$i}\r\n");
}
fclose($fp);
$end_time = microtime(true);
echo "fwrite cost:",($end_time-$start_time),"\r\n";
 
$start_time = microtime(true);
for ($i = 1;$i <= 2; ++$i) {
file_put_contents("file_put_contents.txt","{$i}\r\n",FILE_APPEND);
}
$end_time = microtime(true);
echo "file_put_contents cost:",($end_time-$start_time),"\r\n";

Execution: strace php test.php (assuming the test file name is test)

Output:

......

open("/home/lizhibin/php_fwrite_test/fwrite.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
lseek(3, 0, SEEK_CUR)                   = 0
write(3, "1\r\n", 3)                    = 3
write(3, "2\r\n", 3)                    = 3
close(3)                                = 0
write(1, "fwrite cost:", 12fwrite cost:)            = 12
write(1, "0.0008699893951416", 180.0008699893951416)      = 18
write(1, "\r\n", 2
)                     = 2
getcwd("/home/lizhibin/php_fwrite_test", 4096) = 31
lstat("/home/lizhibin/php_fwrite_test/file_put_contents.txt", 0x7fff415c5c40) = -1 ENOENT (No such file or directory)
open("/home/lizhibin/php_fwrite_test/file_put_contents.txt", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
lseek(3, 0, SEEK_CUR)                   = 0
lseek(3, 0, SEEK_CUR)                   = 0
write(3, "1\r\n", 3)                    = 3
close(3)                                = 0
getcwd("/home/lizhibin/php_fwrite_test", 4096) = 31
lstat("/home/lizhibin/php_fwrite_test/file_put_contents.txt", {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
open("/home/lizhibin/php_fwrite_test/file_put_contents.txt", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
lseek(3, 0, SEEK_CUR)                   = 0
lseek(3, 0, SEEK_CUR)                   = 0
write(3, "2\r\n", 3)                    = 3
close(3)                                = 0

......

Note that the statements marked in red, using file_put_contents, will open the file first when writing, and close the file after writing. However, with fwrite, you only need to open the file once, so it is not surprising to use fwrite blocks.

 

Guess you like

Origin blog.csdn.net/JineD/article/details/111083872