在C#中使用托管API的有效替代方案?

在C#中使用托管API的有效替代方案?,c#,dll,import,C#,Dll,Import,因此,如果我直接使用kernel32来删除我的文件作为例子,它会比这个C#API更有效吗 如果我像这样导入dll并使用DeleteFile(“C:…”): 它的效率会更好吗?例如执行代码所需的时间?唯一确定的方法是测试它。编写代码,创建一大堆临时文件,然后计算删除所有临时文件所需的时间 此处的性能注意事项: 使用本机api删除文件(kernel32)与 由于必须使用编组而导致的性能损失 我的直觉是,如果你真的得到一个,任何性能提升都是微不足道的。删除操作的限制因素是执行文件系统操作,而不是将

因此,如果我直接使用kernel32来删除我的文件作为例子,它会比这个C#API更有效吗

如果我像这样导入dll并使用DeleteFile(“C:…”):


它的效率会更好吗?例如执行代码所需的时间?

唯一确定的方法是测试它。编写代码,创建一大堆临时文件,然后计算删除所有临时文件所需的时间

此处的性能注意事项:

  • 使用本机api删除文件(
    kernel32
    )与
  • 由于必须使用编组而导致的性能损失

我的直觉是,如果你真的得到一个,任何性能提升都是微不足道的。

删除操作的限制因素是执行文件系统操作,而不是将C代码连接到操作系统代码的代码。您将看不到这两个调用之间的明显差异。切换到在这个API中直接调用kernel32肯定是过早的优化。

托管代码速度慢是一个相当常见的误解。通常情况下,您执行的代码与C编译器生成的代码相同,即机器代码。它与作为操作系统函数包装器的大量.Net framework类无关

比如文件类。File.Delete()方法实际上是PinVoke的DeleteFile()winapi函数。当然,这是在Windows上删除文件的唯一方法。NET框架无能为力,至少在托管操作系统可用之前是这样。微软的超级秘密Midori项目的目标就是开发这样一个操作系统

但这是未来的音乐,现在它是一大块C代码,埋在像Fat32或NTFS这样的文件系统驱动程序中,实际上完成了这项工作。它以磁盘速度运行,直到文件系统驱动程序确认删除完成后,DeleteFile()才会返回。非常非常慢。老式硬盘大约50毫秒,SSD的时间在亚毫秒范围内

File.Delete()添加代码,它执行大量错误检查。如果验证传递的参数是否为null,检查代码是否在拒绝文件删除权限的沙箱中运行,检查路径中是否指定了任何在文件路径中不合法的字符,将增量路径转换为完整路径,并检查它是否仍然是合法路径,检查路径字符串是否过长,如有必要,将MS Dos 8.3短名称转换为长名称

这是一系列的工作,但以微秒为单位。如果您pinvoke DeleteFile,那么您将跳过该代码,但最多只能使其快约1%。您将失去的是可靠性,即如果代码或数据中存在oops,您将被告知的保证。有一个非常清晰的异常消息,告诉你到底是什么错了。非常有价值,因为这几微秒乘以10亿仍然无法与调试无法工作的DeleteFile()所花费的时间和痛苦相比


不要这样做。

这看起来像是微优化。你真的需要非常非常快地删除文件吗?删除文件是一个只需很少CPU的I/O操作,我怀疑你在时间上看不到任何差异。虽然这通常是正确的,但在这种特定情况下,我不得不说“从所有实际目的来看,任何开销都可以通过操作成本完全减轻”。另外,标准的.NET方法必须在某种程度上与操作系统进行本机对话..我完全同意;在这里,文件I/O肯定会使您的速度减慢,因此任何性能提升都是微不足道的。感谢您在回答这个问题时花费的时间和精力。
System.IO.File.Delete(string Path);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DeleteFile([MarshalAs(UnmanagedType.LPWStr)]string lpFileName);