当php手册说前者在内部使用后者时,为什么gmmktime()比mktime()更快?

时间:2011-10-17 23:17:21

标签: php performance micro-optimization

根据PHP手册中的gmmktime() description,它在内部使用mktime()。然而,当我运行以下代码时,mktime循环运行时间不到9秒,而gmmktime外观只需不到2秒。怎么会这样?

<?php
$count = 1000000;

$startTime = microtime(true);
for ($i = 0; $i < $count; $i++)
{
  mktime();
}
$endTime = microtime(true);
printf("mktime: %.4f seconds\n", $endTime - $startTime);


$startTime = microtime(true);
for ($i = 0; $i < $count; $i++)
{
  gmmktime();
}
$endTime = microtime(true);
printf("gmmktime: %.4f seconds\n", $endTime - $startTime);

输出:

mktime: 8.6714 seconds
gmmktime: 1.6906 seconds

1 个答案:

答案 0 :(得分:5)

最有可能的是,文档对于gmmktime()如何实现 - 而言,这意味着正在使用 C函数 mktime()

如果我们查看实际代码,gmmktime()mktime()都会传递给内部php_mktime函数,该函数需要gmt参数(设置为{{1}对于1)。如果gmmktime()为零,那么它必须做一些额外的工作(gmt - 我添加的评论,原始代码中的其他评论):

//

我怀疑您可能会发现,每次执行/* Initialize structure with current time */ now = timelib_time_ctor(); if (gmt) { timelib_unixtime2gmt(now, (timelib_sll) time(NULL)); } else { tzi = get_timezone_info(TSRMLS_C); now->tz_info = tzi; now->zone_type = TIMELIB_ZONETYPE_ID; timelib_unixtime2local(now, (timelib_sll) time(NULL)); } // ... snip shared code /* Update the timestamp */ if (gmt) { // NOTE: Setting the tzi parameter to NULL skips a lot of work in timelib_update_ts // (and do_adjust_timezone) timelib_update_ts(now, NULL); } else { timelib_update_ts(now, tzi); } /* Support for the deprecated is_dst parameter */ if (dst != -1) { php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The is_dst parameter is deprecated"); if (gmt) { /* GMT never uses DST */ if (dst == 1) { adjust_seconds = -3600; } } else { /* Figure out is_dst for current TS */ timelib_time_offset *tmp_offset; tmp_offset = timelib_get_time_zone_info(now->sse, tzi); if (dst == 1 && tmp_offset->is_dst == 0) { adjust_seconds = -3600; } if (dst == 0 && tmp_offset->is_dst == 1) { adjust_seconds = +3600; } timelib_time_offset_dtor(tmp_offset); } } 时,它会重新打开时区描述文件以读取它并获得正确的时区/ DST偏移。通过使用mktime(),它可以通过使用GMT的内部空时区来跳过它 - 因此,速度更快。