Reputation: 1845
I am writing code that will do 3 queries to select items that expire within 30 days, 60 days and 90 days:
$arrDates = array("30"=>array(), "60"=>array(), "90"=>array());
$sDateFormat = 'Y-m-d';
$sQuery = "SELECT *
FROM `table
WHERE `expiry_date` BETWEEN "; // Ranges will be added later
foreach ($arrDates as $sInterval=>$arrContainer)
{
$dtStart = new DateTime();
$dtEnd = new DateTime();
$sRangeStart = $dtStart->add(new DateInterval("P{$sInterval}D"))->format("{$sDateFormat} 00:00:00");
$sRangeEnd = $dtEnd->add(new DateInterval("P{$sInterval}D"))->format("{$sDateFormat} 23:59:59");
$arrDates[$sInterval] = fetch_all($sQuery . "'{$sRangeStart}' AND '{$sRangeEnd}'");
}
This code works without any issues. A colleague has suggested that I replace the code inside the foreach loop with the following:
$dtStart = new DateTime();
$dtEnd = new DateTime();
$dtStart->modify("+{$sInterval} days")->setTime(0, 0, 0)->format("{$sDateFormat} 00:00:00");
$dtEnd->modify("+{$sInterval} days")->setTime(23, 59, 59)->format("{$sDateFormat} 23:59:59");
$arrDates[$sInterval] = fetch_all($sQuery . "'{$sRangeStart}' AND '{$sRangeEnd}'");
His reasoning behind this change being that it would mean not having to instantiate 2 DateIntervals every loop. I do not agree with his reasoning mainly because ->modify is an older way of date modification, and I'm not 100% convinced that his way would mean an increase in performance (even though the performance hit we would take either way would be negligible).
If anyone could provide evidence for which way is better (either way is welcome), I'd be most grateful!
Upvotes: 4
Views: 2301
Reputation: 5846
Tested with puting only the add/modify part in the loop and the period was double speed.
modify: 0.029999971389771
add: 0.014999866485596
<?php
$i = 0;
$start = microtime(true);
$date = new DateTime('2018-02-13');
$period = '+5 days';
while ($i++ < 10000) {
$date->modify($period);
}
$end = microtime(true);
echo $date->format('Y-m-d H:i:s'), PHP_EOL;
echo $end - $start, PHP_EOL;
$i = 0;
$start = microtime(true);
$date = new DateTime('2018-02-13');
$period = new DateInterval('P5D');
while ($i++ < 10000) {
$date->add($period);
}
$end = microtime(true);
echo $date->format('Y-m-d H:i:s'), PHP_EOL;
echo $end - $start, PHP_EOL;
Upvotes: 0
Reputation: 337
Please people, for the love of god, do not micro optimize PHP code. We are probably talking about at best milliseconds differences, when, as others have pointed out, most of the time is spent in the database query anyway. In over 25 years of PHP programming, I can count on one hand the cases where an application was slow because of time spent in the PHP code itself, as opposed to external API calls, database queries, etc. And that was even before current PHP versions, which are orders of magnitude faster than, say, PHP 3. One of these cases was a runaway loop, so basically a programming error. And if you ever get into a situation where the PHP code is actually slow, use a profiler to identify the bottleneck. As better programmers than me have pointed out, "premature optimization is the root of all evil".
IMHO you should optimize your PHP code for readability and maintainability, almost never for performance. One good argument against DateInterval is that not every programmer is familiar with it, so, say, $datetime->add(new DateInterval('PT1H')) is not quite as readable as $datetime->modify('+ 1 hour').
BTW. I cannot believe I am saying this, but if you are actually worried about instantiating a DateInterval object in the loop multiple times, just instantiate it outside the loop. But I would not be surprised if the PHP compiler already did that for you without you even noticing.
Upvotes: 2
Reputation: 1089
But without setTime()
is not the same?
$dtStart = new DateTime();
$dtEnd = new DateTime();
$dtStart->modify("+{$sInterval} days")->format("{$sDateFormat} 00:00:00");
$dtEnd->modify("+{$sInterval} days")->format("{$sDateFormat} 23:59:59");
$arrDates[$sInterval] = fetch_all($sQuery . "'{$sRangeStart}' AND '{$sRangeEnd}'");
Upvotes: 0
Reputation: 1038
Both ways are pretty the same, it's a matter of taste how to write code.
For my taste $dt->modify('+5 days')
is more readable than $dt->add(new DateInterval("P5D"))
As for performance, below is a code to test it and results are:
$dt->modify('+5 days') - 0.0503 sec
$dt->add(new DateInterval("P5D")) - 0.0572 sec
so, the readable code is also a very little faster one for the case from the question :)
<?php
$i = 0;
$start = microtime(true);
while($i++ < 10000) {
$date = new DateTime('2018-02-13');
$date->modify('+5 days');
}
$end = microtime(true);
echo $end - $start, "\n";
$i = 0;
$start = microtime(true);
while($i++ < 10000) {
$date = new DateTime('2018-02-13');
$date->add(new DateInterval('P5D'));
}
$end = microtime(true);
echo $end - $start, "\n";
Upvotes: 4