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

发布于 2024-12-10 11:03:06 字数 716 浏览 0 评论 0原文

根据 gmmktime() 描述在 PHP 手册中,它在内部使用 mktime() 。然而,当我运行以下代码时,mktime 循环的运行时间不到 9 秒,而 gmmktime Look 的运行时间不到 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

According to the gmmktime() description in the PHP manual, it uses mktime() internally. Yet when I run the following code, the mktime loop takes just under 9 seconds to run while the gmmktime look takes just under 2 seconds. How can this be?

<?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);

Output:

mktime: 8.6714 seconds
gmmktime: 1.6906 seconds

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

莳間冲淡了誓言ζ 2024-12-17 11:03:06

最有可能的是,文档在如何实现 gmmktime() 方面对您撒了谎 - 它意味着 C 函数 mktime()正在使用。

如果我们查看实际代码,gmmktime()mktime() 都会传递到内部 php_mktime 函数,该函数需要一个 gmt 参数(对于 gmmktime() 设置为 1)。如果 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);
    }
}

我怀疑您可能会发现的是,每次执行 mktime() 时,它都会重新打开时区描述文件来读取它并获取正确的时区/DST 偏移量。通过使用 gmmktime(),它通过使用 GMT 的内部空时区来跳过这一点 - 因此,速度更快。

Most likely, the documentation is lying to you about how gmmktime() is implemented - or it means the C function mktime() is being used.

If we look at the actual code, both gmmktime() and mktime() pass through to an internal php_mktime function, which takes a gmt parameter (set to 1 for gmmktime()). If gmt is zero, then it has to do some extra work (//-comments I have added, others from original code):

/* 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);
    }
}

I suspect what you may find is that, every time you do mktime(), it reopens the timezone description file to read it and get the proper timezone/DST offsets. By using gmmktime(), it skips that by using an internal null timezone for GMT - thus, much faster.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文