【发布时间】:2015-08-31 09:30:07
【问题描述】:
我试图理解为什么多个散列的散列远比一个散列慢。在下面的测试中,我对一个文件进行了两次哈希处理——首先使用 SHA1,然后使用 SHA1 和 SHA256。第一次执行显示了预期的结果 - 磁盘读取占主导地位 - 两者都花费了大约 30 秒(尽管有更多的工作,但后者大约少了一秒)。
但是,在随后的执行中,我得到了一个奇怪的结果:第一次执行大约 10 秒,第二次执行大约 30 秒。 10 表示原始磁盘读取需要 20 秒,30 表示几乎没有时间。这可能真的意味着由于某种原因,散列一次比两次快得多。但为什么呢?
这里发生了什么?
代码:
Text = TestSpeed(new HashAlgorithm[] { new SHA1Managed() }, path);
Text += " " + TestSpeed(new HashAlgorithm[] { new SHA1Managed(), new SHA256Managed() }, path);
还有:
public string TestSpeed(HashAlgorithm[] algorithms, string path)
{
Stopwatch sw = new Stopwatch();
sw.Start();
byte[] block = new byte[65536];
int bytesRead = 0;
using (FileStream stream = new FileStream(path, FileMode.Open))
while ((bytesRead = stream.Read(block, 0, block.Length)) > 0)
foreach (HashAlgorithm algorithm in algorithms)
algorithm.TransformBlock(block, 0, bytesRead, null, 0);
foreach (HashAlgorithm algorithm in algorithms)
algorithm.TransformFinalBlock(block, 0, 0);
sw.Stop();
return sw.Elapsed.ToString();
}
【问题讨论】:
-
你正在重塑
HashAlgorithm.ComputeHash。 referencesource.microsoft.com/#mscorlib/system/security/… -
听起来像缓存,而不是散列......第一次迭代有磁盘 i/o 增加了测试 1 的运行时间,因为测试 2 磁盘读取被缓存。在随后的迭代中,所有读取都被缓存,返回预期的结果。确实,如果此代码很重要,您应该对其进行分析 - 这将清楚地揭示您的执行时间花费在哪里以及它在后续迭代中如何变化。
-
事情太多了。处理器缓存未命中、计算机上的其他任务干扰、磁盘文件碎片等。良好的分析是hard
-
@SLaks 此代码是由我的原始代码编写的,需要逐步散列。
-
@Jay 如果差异很小,或者后续执行不一致 - 我同意。