在我的应用程序中,我有一些记录需要根据一些时间参数进行过滤。要进行日期比较,我需要将记录中的日期(格式为YYYY-MM-DD的字符串)转换为unix时间戳(自1970年以来的秒数)。由于我有成千上万的记录,我真的想找到最有效的方法。
another question的答案建议在数据库中使用strtotime()
或strptime()
,而不是substr
或explode
在数据库中进行此操作(不是这里的选项),但这些感觉就像大多数记忆和时间效率的方法一样,你知道吗?
鉴于我知道输入的确切格式,可能会使用某种形式的字符串操作(mktime
或{{1}})与{{1}}相结合更好吗?
如果你认为我的优化还不成熟,那么只是幽默我好吗?
答案 0 :(得分:5)
为什么你认为strtotime()不是一个有效的功能?你做过任何基准测试吗?请记住,strtotime()是一个内置的库函数,它将直接用C语言编写,而你出现的任何东西都将通过php解释器运行。
另请注意,日期计算本质上很棘手,对闰年和时区等问题也是如此。
至于另一种更快的方法,我认为使用substr()进行解析将比正则表达式更快。将结果输入mktime()并设置。
答案 1 :(得分:2)
strtotime
方式(我的意思是WAAAY)比你能做到的任何事情都要快。
您的记录中的日期有多大可能会被重新编写?如果它们不完全独特,您可以进行某种缓存。假设你在课堂上:
protected $_timestamps = array();
public function toTimestamp($date)
{
if (!array_key_exists($date, $this->_timestamps)) {
$this->_timestamps[$date] = strtotime($date);
}
return $this->_timestamps[$date];
}
现在你必须这样做:
foreach ($records as $record) {
$timestamp = $this->toTimestamp($record->date);
}
答案 2 :(得分:2)
好的,我已经对4种不同的方法进行了基准测试:
function _strtotime($date) {
return strtotime($date);
}
function _preg($date) {
preg_match("@^(\\d+)-(\\d\\d)-(\\d\\d)$@", $date, $matches);
return mktime(0, 0, 0, $matches[2], $matches[3], $matches[1]);
}
function _explode($date) {
list($y,$m,$d) = explode("-", $date);
return mktime(0, 0, 0, $m, $d, $y);
}
function _substr($date) {
$y = substr($date, 0, 4);
$m = substr($date, 5, 2);
$d = substr($date, 8);
return mktime(0, 0, 0, $m, $d, $y);
}
// I also added this one as sort of a "control"
function _hardCoded() {
return mktime(0, 0, 0, 3, 31, 2009);
}
以下是运行每个功能100,000次的结果。输入“2009-03-31”
_hardCoded: 2.02547
_strtotime: 2.35341
_preg: 2.70448
_explode: 2.31173
_substr: 2.27883
答案 3 :(得分:1)
在我看来,如果你真的想要以最有效的方式做到这一点,你将不得不按照你建议的方式,以及你找到的任何其他方式,做一些基准测试,并选择胜利者。< / p>
答案 4 :(得分:0)
由于字符串很好地构建,我将构建从左到右遍历字符串的时间戳。您可以预先构建一个年 - >几秒,几个月 - >的表格。秒,天 - &gt;秒和纠正闰年。乘法是邪恶的:)
或者用更少的努力,构建哈希表以消除重复。
但是你需要很多记录才能更快。听起来你在使用数据库。那与快速不相容......