Skip to content
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

Optimize MD5 performance #140

Merged
merged 1 commit into from
Jul 6, 2023
Merged

Optimize MD5 performance #140

merged 1 commit into from
Jul 6, 2023

Conversation

InCerryGit
Copy link
Member

@InCerryGit InCerryGit commented Jul 6, 2023

In this PR, two things have been done:

1.Standardize file names
2.Optimize MD5 performance

We can reuse the MD5 instance. In fact, in .NET Core, it is already safe to reuse the MD5 instance.

In addition, we can change the hexadecimal conversion to a higher-performance Convert.ToHexString. The following are the results of the performance test, showing a 3-fold performance improvement:

BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1928/22H2/2022Update/SunValley2)
13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores
.NET SDK=7.0.304
  [Host]     : .NET 7.0.7 (7.0.723.27404), X64 RyuJIT AVX2
  DefaultJob : .NET 7.0.7 (7.0.723.27404), X64 RyuJIT AVX2


|       Method |     Mean |   Error |  StdDev |   Gen0 | Allocated |
|------------- |---------:|--------:|--------:|-------:|----------:|
|       MD5Old | 524.5 ns | 4.79 ns | 4.00 ns | 0.0839 |    1056 B |
|       MD5New | 350.7 ns | 2.07 ns | 1.94 ns | 0.0267 |     336 B |
| MD5StaticNew | 171.6 ns | 1.89 ns | 1.77 ns | 0.0165 |     208 B |

Test Code:

using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;


for (int i = 0; i < 100; i++)
{
    var str = $"abc{i}";
    var staticNew = MD5Benchmark.Md5StaticNew(str); 
    var old = MD5Benchmark.Md5Old(str);
    var @new = MD5Benchmark.Md5New(str);
    
    Debug.Assert(old == @new);
    Debug.Assert(old == staticNew);
}

[Orderer]
[MemoryDiagnoser]
public class MD5Benchmark
{

    [Benchmark]
    public void MD5Old()
    {
        _ = MD5Benchmark.Md5Old("Benchmark");
    }

    [Benchmark]
    public void MD5New()
    {
        _ = MD5Benchmark.Md5New("Benchmark");
    }

    [Benchmark]
    public void MD5StaticNew()
    {
        _ = MD5Benchmark.Md5StaticNew("Benchmark");
    }

    public static string Md5Old(string txt)
    {
        using (var md5 = MD5.Create())
        {
            var inputBytes = Encoding.ASCII.GetBytes(txt);
            var hashBytes = md5.ComputeHash(inputBytes);

            // Convert the byte array to hexadecimal string
            var sb = new StringBuilder();
            for (var i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("X2"));
            }
            return sb.ToString();
        }
    }
    
    public static string Md5New(string txt)
    {
        using var md5 = MD5.Create();
        var inputBytes = Encoding.ASCII.GetBytes(txt);
        var hashBytes = md5.ComputeHash(inputBytes);
        return Convert.ToHexString(hashBytes);
    }

    private static readonly MD5 Md5 = MD5.Create();
    public static string Md5StaticNew(string txt)
    {
        var inputBytes = Encoding.ASCII.GetBytes(txt);
        var hashBytes = Md5.ComputeHash(inputBytes);
        return Convert.ToHexString(hashBytes);
    }
}

2.Optimize MD5 performance
@kklldog
Copy link
Collaborator

kklldog commented Jul 6, 2023

Great! Thanks Shi zong!

@kklldog kklldog merged commit 1935079 into dotnetcore:master Jul 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants