I am delighted to announce the release of Spargine 10 (v2026.10.1.5) on January 5th, 2026. Spargine, my open-source project, now offers NuGet packages for .NET 10. These enhancements have been integrated across all my projects. I encourage you to explore these updates and share any feedback or suggestions for further improvements.
This brand-new version, supporting .NET 10, introduces new types, methods, benchmarks, and comprehensive unit tests, all aimed at improving Spargine’s performance and reliability, resulting from over 200 commits. Notably, this release includes speed enhancements informed by benchmark tests outlined in the 5th edition of Rock Your Code: Code & App Performance for Microsoft .NET, available on Amazon.
GitHub: https://github.com/RealDotNetDave/dotNetTips.Spargine.10/
NuGet: http://bit.ly/dotNetDaveNuGet
You can access all the performance data for these assemblies on GitHub. I continually seek assistance with these projects. If you are interested in contributing, please don’t hesitate to contact me via email at dotnetdave@live.com. Your support and collaboration are highly appreciated!
Breaking Changes
With the release of Spargine for .NET 10, I introduced several changes that may break existing code if you’re using these libraries. Many method names were updated to improve clarity and better align with .NET conventions.
Updating your projects to support these changes should be straightforward. In most cases, a simple search-and-replace will handle the update with minimal effort.
New Classes and Methods — Leveling Up Spargine in 2026
Spargine just got a serious upgrade. I’ve packed in a ton of new classes and methods designed to boost performance, clarity, and developer happiness. There are too many to list in full here, so below are the biggest highlights.
Want the full story as it drops? Register on dotNetTips.com, and you’ll get notified when new articles and walkthroughs go live.
dotNetTips.Spargine.Core
| Type | Method | Description |
| App | GenerateDiagnosticReport() | Generates a diagnostic report summarizing application and system information. |
| App | GetLocalizedString() | Retrieves a localized string from the specified resource manager. |
| App | SetAppState() | Sets a value in the application state dictionary. |
| ComputerInfo | DiskUsage | Gets the disk usage information for the computer. |
| ComputerInfo | GetCpuUsageTotalTime | Gets the current CPU usage total time. |
| EncryptionHelper | AesGcmEncrypt() | Encrypts a string using AES-GCM (Galois/Counter Mode) authenticated encryption. |
| EnumHelper | Parse() | Parses the specified string to an enum. |
| InMemoryCache | TryGetValue() | Attempts to get the cache item associated with the specified key. |
| JsonSerialization | LoadCollectionFromJson() | Reads JSON content from a specified file and deserializes it into an array of objects. |
| KeyGenerator | GenerateCustomKey() | Generates a custom key by joining the provided items with a separator and optionally appending a unique key. |
| KeyGenerator | GenerateSortableKey() | Creates a sortable random key from a GUID using version 7 GUIDs. |
| NetworkHelper | GetDnsServerAddresses() | Gets the DNS server addresses configured for the active network interfaces. |
| NetworkHelper | GetLocalIPAddresses() | Gets the local IP addresses for the computer. |
| NetworkHelper | GetNetworkSpeeds() | Gets the network speed (bandwidth) of active network interfaces in bits per second. |
| NetworkHelper | IsConnectedToEthernet() | Checks if the computer is connected to an Ethernet network. |
| NetworkHelper | IsConnectedToWiFi() | Checks if the computer is connected to a Wi-Fi network. |
| PasswordHasher | HashPassword() | Hashes a password using the specified algorithm. |
| PasswordHasher | VerifyHashedPassword() | Verifies a hashed password using the specified algorithm. |
| PerformanceStopWatch | StartNewWithTelemetry() | Starts a new instance of PerformanceStopwatch with telemetry tracking enabled. |
| PerformanceStopWatch | TrackTelemetry() | Tracks telemetry data for the current stopwatch instance using Application Insights. |
| StringBuilderHelper | PerformAction() | Performs the specified action on a StringBuilder instance obtained from an object pool. |
| TypeHelper | GetAllAbstractMethods() | Returns all abstract methods defined on the specified type. |
| TypeHelper | GetAllDeclaredMethods() | Gets all declared methods of the specified type. |
| TypeHelper | GetImplementedInterfaces() | Gets the names of all interfaces implemented by the specified object’s type. |
| Ulid (new type) | NewUlid() | Generates a new ULID (Universally Unique Lexicographically Sortable Identifier). |
dotNetTips.Spargine.Extentions
| Type | Method | Description |
| ArrayExtentions | FastSelectItems() | Selects a range of items from the array using optimized ArraySegment slicing. |
| CountryRepository | GetCountry() | Retrieves a country by its name or ISO code. |
| EnumerableExtentions | FastShuffle() | Shuffles the elements of the collection into a random order using a cryptographically secure random number generator. |
| NumericExtentions | FormatTime() | Formats the time as a human-readable string (e.g., “5 hours 10 minutes 20 seconds” or “20 milliseconds” for values less than 1000). |
| ObjectExtentions | FastBinaryClone() | Creates a deep clone using binary MessagePack serialization (fastest, requires MessagePack attributes). |
| ObjectExtentions | FastClone() | Creates a deep clone of an object by serializing it into JSON and deserializing it back using the provided JsonTypeInfo. |
| ObjectExtentions | FastParseUrl() | Parses a URL string into its constituent components: scheme, host, port, and path. |
| ObjectExtentions | FieldsToDictionary() | Converts an object’s fields into a dictionary, with field names as keys and their values as dictionary values. |
| ObjectExtentions | FieldsToString() | Converts an object’s fields into a string representation. |
| ObjectExtentions | FromJson() | Deserializes a JSON string back into an object using the provided JsonSerializerOptions |
| ObjectExtentions | GetImplementedInterfaces() | Gets the names of all interfaces implemented by the specified object’s type. |
| ObjectExtentions | GetImplementedInterfaceTypes() | Gets all interfaces implemented by the specified object’s type. |
| ObjectExtentions | IsString() | Determines whether the specified object is a string. |
| ObjectExtentions | ToJson() with JsonTypeInfo param | Serializes an object into its JSON string representation using the provided JsonTypeInfo. |
| RandomData | GenerateAddressCollection() | Generates a collection of addresses for a randomly selected country. |
| RandomData | GenerateNonZeroByteArray() | Generates a byte array of a specified size filled with non-zero cryptographically secure random data. |
| RandomData | GenereateAddress() | Generates an address of the specified type: RefTypes.Address, ValueTypes.Address, or AddressRecord. |
| StringBuilderExtentions | SetCapacity() | Sets the capacity of the StringBuilder to the specified value. |
| StringExtentions | CalculateTotalLength() | Calculates the total character count from an array of strings. |
| StringExtentions | FastIsNullOrEmpty() | Determines whether the specified string is null or empty in a fast manner. |
| StringExtentions | FastParseUrl() | Parses a URL string into its constituent components: scheme, host, port, and path. |
| StringExtentions | HashPassword() | Hashes the input string using the specified hashing algorithm. |
| StringExtentions | VerifyHashedPassword() | Verifies the hashed password against the input string using the specified hashing algorithm. |
| TypeExtentions | GetAllConstructors() | Gets all constructors of the specified type, including inherited constructors. |
| TypeExtentions | GetGenericArguments() | Gets the generic type arguments of the specified Type. |
| TypeExtentions | HasMethod() | Determines whether the specified Type has a method with the given name and binding flags. |
| TypeExtentions | HasProperty() | Determines whether the specified Type has a property with the given name. |
| TypeExtentions | ImplementsInterface() | Determines whether the specified Type implements the specified interface type. |
| TypeExtentions | IsAssignableTo() | Determines whether the current Type can be assigned to the specified target type. |
| TypeExtentions | IsClosedGeneric(), IsOpenGeneric() | Determines whether the specified Type is a closed and open generic type. |
| UnitTester | SaveToFile() | Saves the specified input string to a file in the specified directory. |
| UnitTester | SaveToFileAsync() | Asynchronously saves the properties of each object in a collection to a file in the specified directory. |
Performance Enhancements: Significant Speed Improvements Across Methods
With every new release of Spargine, I continue to refine performance — and the .NET 10 version delivers substantial speed gains across many methods. Some improvements came simply from moving Spargine to .NET 10, while others were the result of careful tuning and benchmarking (sometimes with help from Copilot — with mixed results).
Here are a few of the most notable speed increases:
- ArrayExtentions: 24.5x faster
- FastStringBuilder: 208.34x faster
- RandomData: 14x faster
- ReadOnlySpanExtentions: 77.5× faster
- StringBuilderExtentions: 7.18× faster
- StringExtentions: 11.8x faster
- TypeHelper: 2x faster
To accelerate analysis, I now use ChatGPT to compare benchmark results between .NET 8 and .NET 10 — focusing on performance and allocation changes of ±5%. This is dramatically faster than manually reviewing results.
A Word of Caution About Copilot
Do not blindly trust performance suggestions from Copilot.
For this release, I tested many Copilot-generated “optimizations.” Many actually made the code slower — in some cases over 200% slower.
For example, here is the original IndexOf() method in EnumerableExtensions:
public int IndexOf([DisallowNull] T item)
{
collection = collection.ArgumentItemsExists();
item = item.ArgumentNotNull();
var index = 0;
var comparer = EqualityComparer<T>.Default;
foreach (var element in collection)
{
if (comparer.Equals(element, item))
{
return index;
}
index++;
}
return -1;
}
Copilot suggested replacing it with this version:
public int IndexOf([DisallowNull] T item)
{
collection = collection.ArgumentItemsExists();
item = item.ArgumentNotNull();
var comparer = EqualityComparer<T>.Default;
// Special case for arrays for better performance
if (collection is T[] array)
{
for (var arrayIndex = 0; arrayIndex < array.Length; arrayIndex++)
{
if (comparer.Equals(array[arrayIndex], item))
{
return arrayIndex;
}
}
return -1;
}
// Special case for List<T> using Span for better performance
if (collection is List<T> list)
{
var span = CollectionsMarshal.AsSpan(list);
for (var listIndex = 0; listIndex < span.Length; listIndex++)
{
if (comparer.Equals(span[listIndex], item))
{
return listIndex;
}
}
return -1;
}
// Special case for any indexed collection
if (collection is IReadOnlyList<T> readOnlyList)
{
var count = readOnlyList.Count;
for (var readOnlyIndex = 0; readOnlyIndex < count; readOnlyIndex++)
{
if (comparer.Equals(readOnlyList[readOnlyIndex], item))
{
return readOnlyIndex;
}
}
return -1;
}
// Fall back to enumeration for other collection types
var otherIndex = 0;
foreach (var element in collection)
{
if (comparer.Equals(element, item))
{
return otherIndex;
}
otherIndex++;
}
return -1;
}
Looks “smart,” right? In reality — total overkill for this method — and it made performance 206% slower.
Benchmark. Every. Change.
Before accepting any “optimization,” always benchmark before and after. Performance guesses — even AI-assisted ones — are often wrong.
Real data wins. Every time.
Summary
I’m confident these new and enhanced Spargine features will significantly improve your projects by boosting both performance and reliability. Detailed benchmark results are available on GitHub for those who want to dig deeper.
As always, open-source thrives on community involvement. If you find these updates helpful — or have ideas for future improvements — I encourage you to jump in. Whether through pull requests, issue reports, or feature suggestions, your contributions are invaluable.
Together, we can continue to make Spargine a robust and indispensable tool for the .NET community. Your feedback is always welcome, so please share your thoughts in the comments.
If my work has helped you write faster, cleaner, rock-solid .NET code, I’d love your support through GitHub Sponsors. Your sponsorship helps fuel new features, benchmarks, tools, and learning resources for the entire community. Join the crew here: https://github.com/sponsors/RealDotNetDave — and thanks for helping keep the code loud and fast!
Thank you for your support — and keep coding faster, smarter, and better!
Pick up any books by David McCarter by going to Amazon.com: http://bit.ly/RockYourCodeBooks
Make a one-time donation
Make a monthly donation
Make a yearly donation
Choose an amount
Or enter a custom amount
Your contribution is appreciated.
Your contribution is appreciated.
Your contribution is appreciated.
DonateDonate monthlyDonate yearlyIf you liked this article, please buy David a cup of Coffee by going here: https://www.buymeacoffee.com/dotnetdave
© The information in this article is copywritten and cannot be preproduced in any way without express permission from David McCarter.
Discover more from dotNetTips.com
Subscribe to get the latest posts sent to your email.

