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

本文关键字:有效 方案 API | 更新日期: 2023-09-27 17:52:38

所以如果我直接使用kernel32来删除我的文件作为一个例子,它会更有效的替代这个c# API吗?

System.IO.File.Delete(string Path);

如果我像这样导入dll并使用DeleteFile("C:.."):

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DeleteFile([MarshalAs(UnmanagedType.LPWStr)]string lpFileName);

在效率方面是否会更好,例如执行代码所需的时间?

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

认为托管代码很慢是一个相当普遍的误解。通常不是,你执行的代码和C编译器生成的代码是一样的,机器码。它尤其与大量的。net框架类无关,这些类是操作系统函数的包装器。

像File类。File.Delete()方法实际上调用了DeleteFile() winapi函数。这是必须的,这是在Windows上删除文件的唯一方法。. net框架什么也做不了,至少在托管操作系统出现之前是这样。也许有一天真的会发生,微软的超级秘密项目Midori旨在开发这样一个操作系统。

但那是未来的音乐,现在它是一大块C代码,埋在像Fat32或NTFS这样的文件系统驱动程序中,真正完成工作。它以磁盘速度运行,DeleteFile()在文件系统驱动程序确认删除完成之前不会返回。这是非常非常缓慢的。比如老式硬盘大约50毫秒,而SSD则在亚毫秒的范围内。

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

这是一堆工作,但这是以微秒来衡量的。如果您调用DeleteFile,那么您将跳过该代码,但您最多只能使速度提高1%。您将失去的是可靠性,如果您的代码或数据中有错误,您将被告知它的保证。用非常清晰的异常消息告诉您哪里出了问题。非常有价值,因为这几微秒乘以十亿仍然无法与调试不起作用的DeleteFile()所花费的时间和痛苦相比。

别这么做

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

这里的性能考虑:

  • 使用本地api进行文件删除(kernel32)与
  • 的任何可能的性能增益
  • 使用封送造成的性能损失。

这将是我的直觉,任何性能的提高将是微不足道的,如果你得到一个。

删除操作的限制因素是执行文件系统操作,而不是将c#代码连接到操作系统代码的代码。你会发现这两个呼叫之间没有明显的区别。在这个API中切换到直接调用kernel32肯定是一个不成熟的优化。