Skip to content

Commit e8933f2

Browse files
committed
Merging 'dev' branch for release 1.2.0
1 parent 8756dd1 commit e8933f2

92 files changed

Lines changed: 4076 additions & 1297 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/docfx-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Dotnet Setup
2929
uses: actions/setup-dotnet@v4
3030
with:
31-
dotnet-version: 8.x
31+
dotnet-version: 9.x
3232

3333
- run: dotnet tool update -g docfx
3434
- run: docfx Source/Docs/docfx.json

README.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# KZDev.PerfUtils
22

3-
This is the repository for the ['KZDev.PerfUtils'](https://www.nuget.org/packages/KZDev.PerfUtils) nuget package that contains the `MemoryStreamSlim` class; a high-performance, memory-efficient, and easy-to-use replacement for the `MemoryStream` class that provides particular benefits for large or frequently used streams.
3+
This is the repository for the ['KZDev.PerfUtils'](https://www.nuget.org/packages/KZDev.PerfUtils) nuget package that contains the `MemoryStreamSlim` class; a high-performance, memory-efficient, and easy-to-use replacement for the `MemoryStream` class that provides particular benefits for large or frequently used streams. As well as the `StringBuilderCache` which allows better performance when using `StringBuilder` instances, and the `InterlockedOps` class, which provides additional atomic thread-safe operations to extend the functionality of the `Interlocked` class in the .NET Class Library.
44

55
## Features
66

@@ -12,19 +12,38 @@ This is the repository for the ['KZDev.PerfUtils'](https://www.nuget.org/package
1212
* Simple replacement for `MemoryStream` with the same API, other than the constructor.
1313
* Optionally allows using native memory for storage, which allows even more flexibility to minimize GC pressure.
1414

15-
## Future Features
15+
`StringBuilderCache` is a static class that provides a thread-safe cache of `StringBuilder` instances to reduce the number of allocations and deallocations of `StringBuilder` objects in high-throughput scenarios with simple operations:
16+
17+
* Acquire : Get a `StringBuilder` instance from the cache.
18+
* Release : Return a `StringBuilder` instance to the cache.
19+
* GetStringAndRelease : Get the string from a `StringBuilder` instance and return it to the cache.
20+
* GetScope : Get a `using` scoped `StringBuilder` instance from the cache and return it to the cache when the scope is exited.
21+
* Monitoring with `Events` feature of the .NET runtime for detailed cache management.
22+
23+
`InterlockedOps` is a static class providing the following thread-safe atomic operations:
1624

17-
The roadmap plan for this package is to add several additional helpful performance focused utilities. These will be forthcoming as time permits, so this first release is focused just on the `MemoryStreamSlim` class.
25+
* Xor : Exclusive OR operation on any integer types.
26+
* ClearBits : Clear bits on any integer types.
27+
* SetBits : Set bits on any integer types.
28+
* ConditionAnd : Conditionally update bits using an AND operation on any integer types.
29+
* ConditionOr : Conditionally update bits using an OR operation on any integer types.
30+
* ConditionXor : Conditionally update bits using an XOR operation on any integer types.
31+
* ConditionClearBits : Conditionally clear bits on any integer types.
32+
* ConditionSetBits : Conditionally set bits on any integer types.
1833

1934
## Documentation
2035

2136
Full documentation for the package is available on the [PerfUtils Documentation](https://kzdev-net.github.io/kzdev.perfutils/) page.
2237

38+
## Future Features
39+
40+
The roadmap plan for this package is to add several additional helpful performance focused utilities as time allows.
41+
2342
## Contribution Guidelines
2443

2544
At this time, I am not accepting external pull requests. However, any feedback or suggestions are welcome and can be provided through the following channels:
2645

27-
- **Feature Requests:** Please use GitHub Discussions to discuss new new features or enhancements before opening a feature request. This will help ensure that your request is in line with the project's goals and vision.
46+
- **Feature Requests:** Please use GitHub Discussions to discuss new features or enhancements before opening a feature request. This will help ensure that your request is in line with the project's goals and vision.
2847
- **Bug Reports:** If you encounter any issues, feel free to open an issue so it can be addressed promptly.
2948

3049
I appreciate your understanding and look forward to collaborating with you through discussions and issue tracking.

Source/.editorconfig

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none
6868
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
6969
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
7070
dotnet_style_predefined_type_for_member_access = true:suggestion
71-
dotnet_style_qualification_for_field = true:none
7271
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
7372

7473
# ReSharper properties
@@ -147,3 +146,47 @@ csharp_style_expression_bodied_indexers = true:silent
147146
csharp_style_expression_bodied_accessors = true:silent
148147
csharp_style_expression_bodied_lambdas = true:silent
149148
csharp_style_expression_bodied_local_functions = false:silent
149+
csharp_prefer_system_threading_lock = true:suggestion
150+
dotnet_style_qualification_for_field = false:silent
151+
dotnet_style_qualification_for_property = false:silent
152+
dotnet_style_qualification_for_method = false:silent
153+
dotnet_style_qualification_for_event = false:silent
154+
dotnet_style_prefer_compound_assignment = true:suggestion
155+
dotnet_style_prefer_simplified_interpolation = true:suggestion
156+
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
157+
dotnet_style_namespace_match_folder = false:silent
158+
csharp_style_throw_expression = true:suggestion
159+
csharp_style_prefer_null_check_over_type_check = true:suggestion
160+
csharp_prefer_simple_default_expression = true:suggestion
161+
csharp_style_prefer_local_over_anonymous_function = true:suggestion
162+
csharp_style_prefer_index_operator = true:suggestion
163+
csharp_style_prefer_range_operator = true:suggestion
164+
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
165+
csharp_style_prefer_tuple_swap = true:suggestion
166+
csharp_style_inlined_variable_declaration = true:suggestion
167+
csharp_style_deconstructed_variable_declaration = true:suggestion
168+
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
169+
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
170+
dotnet_style_readonly_field = true:suggestion
171+
csharp_prefer_static_local_function = true:suggestion
172+
csharp_prefer_static_anonymous_function = true:suggestion
173+
csharp_style_prefer_readonly_struct = true:suggestion
174+
csharp_style_prefer_readonly_struct_member = true:suggestion
175+
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
176+
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
177+
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
178+
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent
179+
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
180+
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
181+
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
182+
csharp_style_conditional_delegate_call = true:suggestion
183+
dotnet_code_quality_unused_parameters = all:suggestion
184+
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
185+
csharp_style_prefer_switch_expression = true:suggestion
186+
csharp_style_prefer_pattern_matching = true:silent
187+
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
188+
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
189+
csharp_style_prefer_not_pattern = true:suggestion
190+
csharp_style_prefer_extended_property_pattern = true:suggestion
191+
csharp_style_var_when_type_is_apparent = false:silent
192+
csharp_style_var_elsewhere = false:silent
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
namespace KZDev.PerfUtils.Examples
1+
namespace KZDev.PerfUtils.Examples;
2+
3+
public class ConditionXorExample
24
{
3-
public class ConditionXorExample
4-
{
5-
private int _flags;
5+
private int _flags;
66

7-
public bool ToggleFlags (Predicate<int> condition, int flagBits)
8-
{
9-
(int originalValue, int newValue) = InterlockedOps.ConditionXor(ref _flags, condition, flagBits);
10-
return originalValue != newValue;
11-
}
7+
public bool ToggleFlags (Predicate<int> condition, int flagBits)
8+
{
9+
(int originalValue, int newValue) = InterlockedOps.ConditionXor(ref _flags, condition, flagBits);
10+
return originalValue != newValue;
1211
}
13-
}
12+
}
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
namespace KZDev.PerfUtils.Examples
1+
namespace KZDev.PerfUtils.Examples;
2+
3+
public class ConditionClearBitsExample
24
{
3-
public class ConditionClearBitsExample
4-
{
5-
private int _flags;
5+
private int _flags;
66

7-
public bool ClearFlags<T> (Func<int, T, bool> condition, T conditionArgument, int flagBits)
8-
{
9-
(int originalValue, int newValue) = InterlockedOps.ConditionClearBits(ref _flags, condition, conditionArgument, flagBits);
10-
return originalValue != newValue;
11-
}
7+
public bool ClearFlags<T> (Func<int, T, bool> condition, T conditionArgument, int flagBits)
8+
{
9+
(int originalValue, int newValue) = InterlockedOps.ConditionClearBits(ref _flags, condition, conditionArgument, flagBits);
10+
return originalValue != newValue;
1211
}
13-
}
12+
}
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
namespace KZDev.PerfUtils.Examples
1+
namespace KZDev.PerfUtils.Examples;
2+
3+
public class XorExample
24
{
3-
public class XorExample
4-
{
5-
private int _flag;
5+
private int _flag;
66

7-
public bool ToggleFlag ()
8-
{
9-
int originalValue = InterlockedOps.Xor(ref _flag, 1);
10-
return originalValue == 0;
11-
}
7+
public bool ToggleFlag ()
8+
{
9+
int originalValue = InterlockedOps.Xor(ref _flag, 1);
10+
return originalValue == 0;
1211
}
13-
}
12+
}
Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
5-
<ImplicitUsings>enable</ImplicitUsings>
6-
<Nullable>enable</Nullable>
7-
</PropertyGroup>
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
88

9-
<ItemGroup>
10-
<Folder Include="MemoryStreamSlim\" />
11-
</ItemGroup>
9+
<ItemGroup>
10+
<AssemblyAttribute Include="System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage" />
11+
</ItemGroup>
1212

13-
<ItemGroup>
14-
<ProjectReference Include="..\..\Src\KZDev.PerfUtils\KZDev.PerfUtils.csproj" />
15-
</ItemGroup>
13+
<ItemGroup>
14+
<ProjectReference Include="..\..\Src\KZDev.PerfUtils\KZDev.PerfUtils.csproj" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<Folder Include="MemoryStreamSlim\" />
19+
</ItemGroup>
1620

1721
</Project>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Text;
2+
3+
namespace KZDev.PerfUtils.Examples;
4+
5+
public class StringBuilderExample
6+
{
7+
public static void SimpleRelease ()
8+
{
9+
StringBuilder stringBuilder = StringBuilderCache.Acquire();
10+
stringBuilder.Append("Hello, ");
11+
stringBuilder.Append("World!");
12+
Console.WriteLine(stringBuilder.ToString());
13+
StringBuilderCache.Release(stringBuilder);
14+
}
15+
16+
public static void GetStringAndRelease ()
17+
{
18+
StringBuilder stringBuilder = StringBuilderCache.Acquire();
19+
stringBuilder.Append("Hello, ");
20+
stringBuilder.Append("World!");
21+
Console.WriteLine(StringBuilderCache.GetStringAndRelease(stringBuilder));
22+
}
23+
24+
public static void GetScopeAndString()
25+
{
26+
using StringBuilderScope builderScope = StringBuilderCache.GetScope();
27+
StringBuilder builder = builderScope.Builder;
28+
builder.Append("Hello, ");
29+
builder.Append("World!");
30+
Console.WriteLine(builderScope.ToString());
31+
}
32+
}

0 commit comments

Comments
 (0)