-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Analyzer / fixer proposal: Prefer static HashData methods over ComputeHash #40579
Analyzer / fixer proposal: Prefer static HashData methods over ComputeHash #40579
Comments
This makes sense. |
Which severity should this be? |
Probably suggestion / informational / etc.? We tend to keep perf-focused analyzers low severity unless the caller is doing something egregiously wrong. |
I see. |
Is the bottom line that the using can be skipped by using the static HashData? |
|
What Jeremy said... it's simpler and faster.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Security.Cryptography;
[MemoryDiagnoser]
public class Program
{
public static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
private readonly byte[] _data = RandomNumberGenerator.GetBytes(128);
[Benchmark(Baseline = true)]
public byte[] WithInstance()
{
using (var sha256 = SHA256.Create())
{
return sha256.ComputeHash(_data);
}
}
[Benchmark]
public byte[] WithStatic()
{
return SHA256.HashData(_data);
}
} |
Well that is pretty great guys. I came accross this in a pretty random way. I saw methods using using |
It depends on your needs. If you already have a destination span you want the results written to, call the overload that takes a destination span. Otherwise call the overload that creates the result array on your behalf.
Depends on the OS. For example, we may keep a shared handle around and keep reusing it. Or we may call a specialty OS API under the covers. This is just an implementation detail and callers shouldn't need to worry about it. |
That is great thank you. I think the docs should explain this somehow, I was updating a library I had from .Net Standard and somehow came to this thread by chance. The compute hash method is not labelled as obsolete. |
@stephentoub , the allocation ratio is huge! (240/56) |
That's because it's only allocating the resulting byte[] now rather than also allocating the SHA256 instance and associated state. |
The docs should explain what, specifically? The existing |
Explain the difference in usage, and also provide examples as done above. If not to be obsoleted, then explain in what scenario the old method would be better, e.g. for projects targeting .Net5+ the static version seems better. |
Does the skipping of the using statement also applies to
Or should we use
? |
You should use the static members when possible on |
Speaking more broadly, there has been a lot of "staticification" of the crypto stuff in .NET:
Similarly,
|
Thank you for the detailed info @vcsjones and what you have done sounds great and surely welcomed. |
@jeffhandley should this be in 6.0 at this point? |
Category: performance, improved linker trimming efficiency (is that even a category?)
We should consider an analyzer that can detect this pattern:
And suggest the code instead use this pattern:
Using one-shot hashing APIs like this is a bit more foolproof than using the normal stateful instance members on these types.
The analyzer should detect the pattern where a
HashAlgorithm
instance is created (either viaSHA256.Create
,new SHA256Managed
, ornew SHA256CryptoServiceProvider
; or via the MD5 / SHA* equivalents), there is a single call made toHashAlgorithm.ComputeHash(byte[])
, then there is an optional call made toDispose
.The analyzer should only trigger for projects targeting net5.0+, as that's when the new static APIs were introduced.
See also: #17590, dotnet/aspnetcore#24696, dotnet/wpf#3318
The text was updated successfully, but these errors were encountered: