35

有谁知道gettimeofday()Windows 环境中该功能的等效功能?我正在比较 Linux 和 Windows 中的代码执行时间。我正在使用 MS Visual Studio 2010,它一直说,标识符“gettimeofday”未定义。

4

6 回答 6

79

这是一个免费的实现:

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdint.h> // portable: uint64_t   MSVC: __int64 

// MSVC defines this in winsock2.h!?
typedef struct timeval {
    long tv_sec;
    long tv_usec;
} timeval;

int gettimeofday(struct timeval * tp, struct timezone * tzp)
{
    // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
    // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
    // until 00:00:00 January 1, 1970 
    static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);

    SYSTEMTIME  system_time;
    FILETIME    file_time;
    uint64_t    time;

    GetSystemTime( &system_time );
    SystemTimeToFileTime( &system_time, &file_time );
    time =  ((uint64_t)file_time.dwLowDateTime )      ;
    time += ((uint64_t)file_time.dwHighDateTime) << 32;

    tp->tv_sec  = (long) ((time - EPOCH) / 10000000L);
    tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
    return 0;
}
于 2014-09-28T14:21:19.987 回答
16

GetLocalTime()对于系统时区中的时间,GetSystemTime()对于 UTC。那些返回结构中的日期/时间SYSTEMTIME,将其解析为年、月等。如果您想要一个自纪元以来的秒数时间,请使用SystemTimeToFileTime()or GetSystemTimeAsFileTime()。这FILETIME是一个 64 位值,自 1601 年 1 月 1 日 UTC 以来的间隔数为 100ns。

对于间隔拍摄,使用GetTickCount(). 它返回自启动以来的毫秒数。

要以最佳分辨率(仅受硬件限制)获取间隔,请使用QueryPerformanceCounter().

于 2012-06-05T22:35:22.160 回答
8

这是使用chrono的 c++11 版本。

谢谢你,霍华德欣南特的建议。

#if defined(_WIN32)
#include <chrono>

int gettimeofday(struct timeval* tp, struct timezone* tzp) {
  namespace sc = std::chrono;
  sc::system_clock::duration d = sc::system_clock::now().time_since_epoch();
  sc::seconds s = sc::duration_cast<sc::seconds>(d);
  tp->tv_sec = s.count();
  tp->tv_usec = sc::duration_cast<sc::microseconds>(d - s).count();

  return 0;
}

#endif // _WIN32
于 2019-09-30T05:51:19.253 回答
4

如果你真的想要一个 Windows gettimeofday() 实现,这里有一个来自 PostgreSQL的,它使用 Windows API 和正确的转换。

但是,如果您想对代码进行计时,我建议您查看QueryPerformanceCounter()或者如果您只打算在 x86 上运行,则直接调用 TSC 。

于 2012-06-06T03:14:41.223 回答
4

现在,我将在 Windows 上将以下内容用于 gettimeofday(),如果为 Windows 8 或更高版本编译,则使用 GetSystemTimePreciseAsFileTime(),否则使用 GetSystemTimeAsFileTime():

#include <Windows.h>
struct timezone {
    int tz_minuteswest;
    int tz_dsttime;
};

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
    if (tv) {
        FILETIME               filetime; /* 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 00:00 UTC */
        ULARGE_INTEGER         x;
        ULONGLONG              usec;
        static const ULONGLONG epoch_offset_us = 11644473600000000ULL; /* microseconds betweeen Jan 1,1601 and Jan 1,1970 */

#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
        GetSystemTimePreciseAsFileTime(&filetime);
#else
        GetSystemTimeAsFileTime(&filetime);
#endif
        x.LowPart =  filetime.dwLowDateTime;
        x.HighPart = filetime.dwHighDateTime;
        usec = x.QuadPart / 10  -  epoch_offset_us;
        tv->tv_sec  = (time_t)(usec / 1000000ULL);
        tv->tv_usec = (long)(usec % 1000000ULL);
    }
    if (tz) {
        TIME_ZONE_INFORMATION timezone;
        GetTimeZoneInformation(&timezone);
        tz->tz_minuteswest = timezone.Bias;
        tz->tz_dsttime = 0;
    }
    return 0;
}
于 2019-12-16T15:44:31.017 回答
0

自 Visual Studio 2015 以来,timespec_get可用:

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static uint64_t
time_ns(void)
{
    struct timespec ts;

    if (timespec_get(&ts, TIME_UTC) != TIME_UTC)
    {
        fputs("timespec_get failed!", stderr);
        return 0;
    }
    return 1000000000 * ts.tv_sec + ts.tv_nsec;
}

int main(void)
{
    printf("%" PRIu64 "\n", time_ns());
    return EXIT_SUCCESS;
}

编译使用cl t.c并运行:

C:\> perl -E "system 't' for 1 .. 10"
1626610781959535900
1626610781973206600
1626610781986049300
1626610781999977000
1626610782014814800
1626610782028317500
1626610782040880700
1626610782054217800
1626610782068346700
1626610782081375500
于 2021-07-18T12:20:39.367 回答