Skip to content

Commit ada0018

Browse files
mdesalvoclaude
andcommitted
Reuse a per-thread MD5 engine in CreateHash
Avoids allocating and initializing a fresh MD5CryptoServiceProvider on every hash (the bulk-load hot path) by caching a [ThreadStatic] MD5 instance. MD5 is not thread-safe, so each thread keeps its own engine; the produced digest is identical to before, so all triple/member IDs are unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 0aef38c commit ada0018

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

RDFSharp/Model/RDFModelUtilities.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ namespace RDFSharp.Model
3434
public static class RDFModelUtilities
3535
{
3636
#region Hashing
37+
/// <summary>
38+
/// Per-thread reusable MD5 engine. MD5 is not thread-safe, so each thread keeps its own instance:
39+
/// this avoids allocating/initializing a fresh crypto provider on every hash (the bulk-load hot path)
40+
/// while preserving the exact same digest produced by the former per-call MD5CryptoServiceProvider.
41+
/// </summary>
42+
[ThreadStatic]
43+
private static MD5 MD5Engine;
44+
3745
/// <summary>
3846
/// Creates a unique long representation of the given string
3947
/// </summary>
@@ -45,8 +53,8 @@ public static long CreateHash(string input)
4553
throw new RDFModelException("Cannot create hash because given \"input\" string parameter is null.");
4654
#endregion
4755

48-
using (MD5CryptoServiceProvider md5Encryptor = new MD5CryptoServiceProvider())
49-
return BitConverter.ToInt64(md5Encryptor.ComputeHash(UTF8_NoBOM.GetBytes(input)), 0);
56+
MD5 md5Encryptor = MD5Engine ?? (MD5Engine = MD5.Create());
57+
return BitConverter.ToInt64(md5Encryptor.ComputeHash(UTF8_NoBOM.GetBytes(input)), 0);
5058
}
5159
#endregion
5260

0 commit comments

Comments
 (0)