c# – 调用Windows API时CLR的速度比我快
发布时间:2020-12-15 03:51:28 所属栏目:百科 来源:网络整理
导读:当我发现一些令人惊讶的事情(对我来说),我测试了不同的生成时间戳的方式. 使用P / Invoke调用Windows的GetSystemTimeAsFileTime比调用DateTime.UtcNow慢约3倍,内部使用CLR的包装器来获取相同的GetSystemTimeAsFileTime. 怎么可能? 这是 DateTime.UtcNow ‘s
当我发现一些令人惊讶的事情(对我来说),我测试了不同的生成时间戳的方式.
使用P / Invoke调用Windows的GetSystemTimeAsFileTime比调用DateTime.UtcNow慢约3倍,内部使用CLR的包装器来获取相同的GetSystemTimeAsFileTime. 怎么可能? 这是 public static DateTime UtcNow { get { long ticks = 0; ticks = GetSystemTimeAsFileTime(); return new DateTime( ((UInt64)(ticks + FileTimeOffset)) | KindUtc); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] // Implemented by the CLR internal static extern long GetSystemTimeAsFileTime(); 核心CLR的wrapper for FCIMPL0(INT64,SystemNative::__GetSystemTimeAsFileTime) { FCALL_CONTRACT; INT64 timestamp; ::GetSystemTimeAsFileTime((FILETIME*)×tamp); #if BIGENDIAN timestamp = (INT64)(((UINT64)timestamp >> 32) | ((UINT64)timestamp << 32)); #endif return timestamp; } FCIMPLEND; 我的测试代码利用BenchmarkDotNet: public class Program { static void Main() => BenchmarkRunner.Run<Program>(); [Benchmark] public DateTime UtcNow() => DateTime.UtcNow; [Benchmark] public long GetSystemTimeAsFileTime() { long fileTime; GetSystemTimeAsFileTime(out fileTime); return fileTime; } [DllImport("kernel32.dll")] public static extern void GetSystemTimeAsFileTime(out long systemTimeAsFileTime); } 结果: Method | Median | StdDev | ------------------------ |----------- |---------- | GetSystemTimeAsFileTime | 14.9161 ns | 1.0890 ns | UtcNow | 4.9967 ns | 0.2788 ns | 解决方法
CLR几乎肯定会传递一个指向本地(自动,堆栈)变量的指针来接收结果.堆栈没有被压缩或重新定位,所以不需要引导内存等,当使用本地编译器时,这样的东西不支持,所以没有开销来解释它们.
在C#中,p / invoke声明与传递生活在垃圾回收堆中的受管理类实例的成员兼容. P / invoke必须固定该实例,否则在OS功能写入之前/之前有输出缓冲区的风险.即使您传递存储在堆栈上的变量,p / invoke仍然必须测试,看看指针是否进入垃圾回收堆,然后才能分支到固定代码,因此即使在相同的情况下也会有非零开销. 你可以使用更好的结果 [DllImport("kernel32.dll")] public unsafe static extern void GetSystemTimeAsFileTime(long* pSystemTimeAsFileTime); 通过消除out参数,p / invoke不再需要处理别名和堆压缩,现在完全是您设置指针的代码的责任. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |