我正在编写一个控制台应用程序,它遍历二叉树并根据其md5校验和搜索新的或更改的文件。 整个过程可以快速接受(约70,000个文件需要14秒),但生成校验和需要大约5分钟,这太慢了......
有关改进此流程的任何建议吗?我的哈希函数如下:
private string getMD5(string filename)
{
using (var md5 = new MD5CryptoServiceProvider())
{
if (File.Exists(@filename))
{
try
{
var buffer = md5.ComputeHash(File.ReadAllBytes(filename));
var sb = new StringBuilder();
for (var i = 0; i < buffer.Length; i++)
{
sb.Append(buffer[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception)
{
Program.logger.log("Error while creating checksum!", Program.logger.LOG_ERROR);
return "";
}
}
else
{
return "";
}
}
}
答案 0 :(得分:2)
嗯,接受的答案无效,因为当然有一些方法可以提高代码性能。它适用于其他一些想法但是)
除磁盘I / O外,此处的主要停止是内存分配。这里有一些想要提高速度的想法:
ComputeHash
流覆盖时减速,因为在内部使用非常小的缓冲区(4kb),所以选择适当的缓冲区大小(256kb或更多,通过实验找到最佳值)< / LI>
outputBuffer
参数传递null。MD5CryptoServiceProvider
,但好处是有问题的。以上所有内容均适用于中型到大型文件。相反,如果你有很多非常小的文件,你可以通过并行处理文件来加快计算速度。实际上,并行化也可以帮助处理大文件,但是需要对其进行测量。
最后,如果碰撞没有太多困扰你,你可以选择较便宜的哈希算法,例如CRC。
答案 1 :(得分:1)
为了创建Hash,您必须读取文件的每个最后一个字节。因此,此操作受磁盘限制,不受CPU限制,并且与文件大小成比例。多线程无济于事。
除非FS能够以某种方式为您计算和存储哈希值,否则无法加快速度。您依赖于FS为您跟踪更改所做的工作。
通常用于检查&#34;更改文件的程序&#34; (就像备份例程一样)不计算Hashvalue就是出于这个原因。他们仍然可以计算和存储它以用于验证目的,但就是这样。
除非用户做了一些严重的(NTFS驱动程序加载级别)破坏,否则&#34;最后一次更改&#34;使用filesize的日期足以检测更改。也许还要检查存档位,但现在很少使用它。
对于这些场景(列出文件并处理它们)的微小改进是使用&#34; Enumerate Files&#34;而不是列出文件。但在14秒上市/ 5分钟处理将没有任何相关效果。