php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48828 strtotime() seems surprisingly slow (3x worse than preg_match).
Submitted: 2009-07-07 05:05 UTC Modified: 2009-07-15 01:00 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: php at richardneill dot org Assigned:
Status: No Feedback Package: Performance problem
PHP Version: 6CVS-2009-07-07 (CVS) OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: php at richardneill dot org
New email:
PHP Version: OS:

 

 [2009-07-07 05:05 UTC] php at richardneill dot org
Description:
------------
I've just been troubleshooting a script whose job is to fix 
logfiles. Each line of the logfile has a timestamp, but only
HH:MM:SS and it's missing the date. My script has to fix this.

For a 500,000 line file, this takes about 2 minutes, so I 
investigated further. I found that strtotime() was really quite a 
lot slower than I expected, and that using preg_match() instead 
doubled the script execution speed.

Is this really to be expected, or could strtotime() be optimised?


Reproduce code:
---------------
#!/usr/bin/php
<?

//This demonstrates that strtotime() is really rather slow. The 
//example is quite contrived, but surely it should be possible to 
//make strtotime() much faster than an entire regular-expression
//match, rather than 3 times slower?

$time1=microtime(1);

$timestamp1="05:03:02";
$timestamp2="03:05:07";

for ($i=0;$i<1E6;$i++){
	$seconds = strtotime($timestamp1)  - strtotime($timestamp2);
	#echo "$seconds\n"; //Do something with $seconds
}

$time2=microtime(1);

for ($i=0;$i<1E6;$i++){
	//preg_match lets us both check that this IS a valid
        //timestamp and split it into parts.
	preg_match('/^(\d\d):(\d\d):(\d\d)(\.\d+)?$/', $timestamp1, $matches1);
	preg_match('/^(\d\d):(\d\d):(\d\d)(\.\d+)?$/', $timestamp2, $matches2);

	$seconds = ( 3600 * intval($matches1[1]) + 60 *
        intval($matches1[2]) + intval($matches1[3]) ) -
	( 3600 * intval($matches2[1]) + 60 * 
        intval($matches2[2]) + intval($matches2[3])  );
	#echo "$seconds\n";  //Do something with $seconds
}

$time3=microtime(1);

# 42.8 on 2.4GHz CPU
echo "Each pair of calls to strtotime() took:".($time2 - $time1 )." microseconds \n";
   
# 16.6.
echo "Each pair of calls to preg_match() etc took:".($time3 - $time2 )." microseconds \n";
?>

Expected result:
----------------
I expect strtotime(), which is designed specifically for the 
purpose, to be faster than preg_match, which is more 
general-purpose.

Actual result:
--------------
strtotime() takes about 3 x longer than the brute-force approach 
using a regular-expression + array maths. Is that really expected?
date() isn't very fast either.

42us means 100,000 CPU cycles!


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-07-07 05:07 UTC] rasmus@php.net
Have you set your timezone in your php.ini?  I don't see it set in your script.  And is this actually PHP6?
 [2009-07-15 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 23 23:01:29 2024 UTC