gpt4 book ai didi

c# - HashAlgorithm.ComputeHash() 是线程安全的吗?

转载 作者:行者123 更新时间:2023-12-05 01:23:00 27 4
gpt4 key购买 nike

我无法得到关于这个问题的明确答案,所以这个问题。过去很少有 SO 帖子提到 HashAlgorithm 的实例在 MSDN 文档中不是线程安全的引用片段。

但是,current MSDN doc没有这么说。令人惊讶的是,下面的代码不会在 net3.1、net5.0 上爆炸,但在 net6.0 上。所以,看起来它是线程安全的(也许),但也许 net6.0 有一个错误。

//<TargetFrameworks>net6.0;net5.0;netcoreapp3.1;net48</TargetFrameworks>
[Explicit]
[Test]
public void Bork_HashAlgorithm()
{
const int iterations = 1_000_000;
var bytes = Encoding.UTF8.GetBytes("the overtinkerer");
using (var md5 = MD5.Create())
{
Parallel.For(0, iterations, (i, loop) =>
{
md5.ComputeHash(bytes);
});
}
}

异常信息:

SafeHandle cannot be null. (Parameter 'pHandle')

最佳答案

不,它不是线程安全的。

我们在峰值负载下看到了相同的异常:SafeHandle 不能为 null。 (参数“pHandle”) 以及 MD5 提供程序、SHA1 和 SHA256 的类似错误,到处都是。

但是我们发现使用带有HashAlgorithm的“单例”实例仍然是有益的,它仍然比每次创建一个单独的实例快 3 倍时间。

这是基准

<表类="s-表"><头>方法均值错误标准偏差Gen0第一代第二代已分配<正文>MD5重新创建1,282.5 纳秒726.26 纳秒39.81 纳秒0.08010.02860.0038512 BMD5SingletonWithLock402.2 纳秒39.38 纳秒2.16 纳秒0.0610--384 BMD5_哈希数据467.7 纳秒33.26 纳秒1.82 纳秒0.0548--344 B

代码如下:

static MD5 _md5 = MD5.Create(); // <-- one instance for all threads
public static byte[] MD5Hash(byte[] input)
{
lock (_md5) // <-- use a lock
{
return _md5.ComputeHash(input);
}
}

更新:我还对 .NET 5 中引入的新静态 MD5.HashData 方法进行了基准测试——它并不比使用 lock 快。然而,MD5.HashData 在重度并行性下表现出更好的性能,这是 BDN 无法模拟的(参见下面的评论)

更新 2:添加 SHA256 基准

<表类="s-表"><头>方法均值错误标准偏差Gen0第一代已分配<正文>分享再造2.211 us3.7097 us0.2033 us0.11440.0534736 BSHASingletonWithLock1.231 us0.1349 us0.0074 us0.0954-608 BSHA_哈希数据1.296 us0.0737 us0.0040 us0.0877-552 B

警告:

请注意有关并行度的评论 here .

关于c# - HashAlgorithm.ComputeHash() 是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73006466/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com