Ale*_*rin 2 php performance micro-optimization
根据PHP手册中的gmmktime()描述,它在内部使用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);
Run Code Online (Sandbox Code Playgroud)
输出:
mktime: 8.6714 seconds
gmmktime: 1.6906 seconds
Run Code Online (Sandbox Code Playgroud)
最有可能的是,文档向您说明如何gmmktime()实现 - 或者它意味着正在使用C函数 mktime().
如果我们看一下实际的代码,都gmmktime()并mktime()通过一个内部php_mktime函数,它接受一个gmt参数(设置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);
}
}
Run Code Online (Sandbox Code Playgroud)
我怀疑你可能会发现,每次你这样做mktime(),它会重新打开时区描述文件来读取它并获得适当的时区/ DST偏移.通过使用gmmktime(),它通过使用GMT的内部空时区来跳过它 - 因此,更快.