既然你都看到源码了,那就看下 Java 为什么快吧。
从 jdk11 中可以看到 Windows 获取时间使用的函数是 GetSystemTimeAsFileTime ;
https://github.com/openjdk/jdk/blob/jdk-11+28/src/hotspot/os/windows/os_windows.cpp#L917再看.net6 ,
可以看到.net 在系统支持时会使用更精确的时间函数 GetSystemTimePreciseAsFileTime ;
https://github.com/dotnet/runtime/blob/v6.0.8/src/libraries/System.Private.CoreLib/src/System/DateTime.Windows.cs#L134GetSystemTimePreciseAsFileTime 函数在 win8 以上受支持:
https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime#requirements这是一个慢的点。
但是.net 的 DateTime 精度更高。
另外.net 还会计算闰秒:
https://github.com/dotnet/runtime/blob/v6.0.8/src/libraries/System.Private.CoreLib/src/System/DateTime.Windows.cs#L23这是第二个慢的点。也是为了精度考虑的。
当然你可以说是.net 的“过度设计”,你不需要精确时间。。。那这个确实就需要自己动手了:
public unsafe static class SlimDateTime
{
private const long TicksPerMillisecond = 10000;
private const long TicksPerSecond = TicksPerMillisecond * 1000;
private const long TicksPerMinute = TicksPerSecond * 60;
private const long TicksPerHour = TicksPerMinute * 60;
private const long TicksPerDay = TicksPerHour * 24;
private const int DaysTo1601 = 584388;
private const int DaysTo1970 = 719162;
private const long FileTimeOffset = DaysTo1601 * TicksPerDay;
private const ulong KindUtc = 0x4000000000000000;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static DateTime UtcNow()
{
var ticks = GetTicks();
return *(DateTime*)&ticks;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetTicks() => OperatingSystem.IsWindows() ? Windows.GetTicks() : (ulong)DateTime.UtcNow.Ticks;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong UtcNowUnixTimeMilliseconds() => OperatingSystem.IsWindows() ? Windows.UtcNowUnixTimeMilliseconds() : (ulong)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
private static class Windows
{
[DllImport("kernel32", EntryPoint = "GetSystemTimeAsFileTime")]
[SuppressGCTransition]
public extern static void GetSystemTimeAsFileTime(ulong* time);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetTicks()
{
ulong fileTime;
GetSystemTimeAsFileTime(&fileTime);
return fileTime + (FileTimeOffset | KindUtc);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong UtcNowUnixTimeMilliseconds()
{
ulong fileTime;
GetSystemTimeAsFileTime(&fileTime);
return (fileTime - ((DaysTo1970 - DaysTo1601) * TicksPerDay)) / TicksPerMillisecond;
}
}
}
其他的就不评价了,懒得打字;