我有一些非常慢的代码。我就知道会这样,现在也是了。基本上,我是从一堆目录中读取文件。文件名会更改,但数据不会更改。为了确定我是否已经读取了该文件,我散列了它的字节,并将其与已经处理的文件的散列列表进行了比较。每个目录中大约有1000个文件,找出每个目录中的新内容需要一分钟左右的时间(然后处理开始)。下面是基本代码:
public static class ProgramExtensions
{
public static byte[] ToSHA256Hash(this FileInfo file)
{
using (FileStream fs = new FileStream(file.FullName, FileMode.Open))
{
using (SHA256 hasher = new SHA256Managed())
{
return hasher.ComputeHash(fs);
}
}
}
public static string ToHexString(this byte[] p)
{
char[] c = new char[p.Length * 2 + 2];
byte b;
c[0] = '0'; c[1] = 'x';
for (int y = 0, x = 2; y < p.Length; ++y, ++x)
{
b = ((byte)(p[y] >> 4));
c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
b = ((byte)(p[y] & 0xF));
c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
}
return new string(c);
}
}
class Program
{
static void Main(string[] args)
{
var allFiles = new DirectoryInfo("c:\\temp").GetFiles("*.*");
List<string> readFileHashes = GetReadFileHashes();
List<FileInfo> filesToRead = new List<FileInfo>();
foreach (var file in allFiles)
{
if (readFileHashes.Contains(file.ToSHA256Hash().ToHexString()))
filesToRead.Add(file);
}
//read new files
}
}有没有什么我可以加快速度的方法?
发布于 2009-06-09 21:52:24
我相信你可以通过首先检查文件大小来实现最显著的性能改进,如果文件大小不匹配,你可以跳过整个文件,甚至不打开它。
除了保存已知散列的列表之外,您还将保留已知文件大小的列表,并且仅在文件大小匹配时才进行内容比较。当文件大小不匹配时,您甚至可以省去查看文件内容。
根据文件的一般大小,进一步改进可能是值得的:
当第一个字节不同时,
我怀疑改变散列算法本身(例如第一次检查,按照建议做CRC )是否会有任何显着的不同。您的瓶颈可能是磁盘IO,而不是CPU,因此避免磁盘IO会给您带来最大的改进。但一如既往地在性能上,做了度量。
然后,如果这仍然不够(也只有到那时),尝试异步IO (请记住,尽管顺序读取通常比随机访问更快,因此过多的随机异步读取可能会损害您的性能)
发布于 2009-06-09 21:53:36
发布于 2009-06-09 22:15:15
请参阅http://en.wikipedia.org/wiki/List_of_checksum_algorithms#Computational_costs_of_CRCs_vs_Hashes
通过采样实现真正简单的校验和(例如,checksum =(前10字节和后10字节))是否有效?
https://stackoverflow.com/questions/972667
复制相似问题