-
Notifications
You must be signed in to change notification settings - Fork 0
V10.0.1/service update #14
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
Changes from all commits
1e4ba54
03bd279
9971f0f
d8ec846
680858a
67337eb
62ac0be
c25772c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,164 @@ | ||
| --- | ||
| mode: agent | ||
| description: 'Writing Performance Benchmarks' | ||
| --- | ||
|
|
||
| # Benchmark Fixture Prompt (Tuning Benchmarks) | ||
|
|
||
| This prompt defines how to generate performance tests (“benchmarks”) for a project/solution using BenchmarkDotNet. | ||
| Benchmarks are *not* unit tests — they are micro- or component-level performance measurements that belong under the `tuning/` directory and follow strict conventions. | ||
|
|
||
| Copilot must follow these guidelines when generating benchmark fixtures. | ||
|
|
||
| --- | ||
|
|
||
| ## 1. Naming and Placement | ||
|
|
||
| - All benchmark projects live under the `tuning/` folder. | ||
| Examples: | ||
| - `tuning/<ProjectName>.Benchmarks/` | ||
| - `tuning/<ProjectName>.Console.Benchmarks/` | ||
|
|
||
| - **Namespaces must NOT end with `.Benchmarks`.** | ||
| They must mirror the production assembly’s namespace. | ||
|
|
||
| Example: | ||
| If benchmarking a type inside `YourProject.Console`, then: | ||
|
|
||
| ```csharp | ||
| namespace YourProject.Console | ||
| { | ||
| public class Sha512256Benchmark { … } | ||
| } | ||
| ``` | ||
|
|
||
| * **Benchmark class names must end with `Benchmark`.** | ||
| Example: `DateSpanBenchmark`, `FowlerNollVoBenchmark`. | ||
|
|
||
| * Benchmark files should be located in the matching benchmark project | ||
| (e.g., benchmarks for `YourProject.Console` go in `YourProject.Console.Benchmarks.csproj`). | ||
|
|
||
| * In the `.csproj` for each benchmark project, set the root namespace to the production namespace, for example: | ||
|
|
||
| ```xml | ||
| <RootNamespace>YourProject.Console</RootNamespace> | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 2. Attributes and Configuration | ||
|
|
||
| Each benchmark class should use: | ||
|
|
||
| ```csharp | ||
| [MemoryDiagnoser] | ||
| [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] | ||
| ``` | ||
|
|
||
| Optional but strongly recommended where meaningful: | ||
|
|
||
| * `[Params(...)]` — define small, medium, large input sizes. | ||
| * `[GlobalSetup]` — deterministic initialization of benchmark data. | ||
| * `[Benchmark(Description = "...")]` — always add descriptions. | ||
| * `[Benchmark(Baseline = true)]` — when comparing two implementations. | ||
|
|
||
| Avoid complex global configs; prefer explicit attributes inside the class. | ||
|
|
||
| --- | ||
|
|
||
| ## 3. Structure and Best Practices | ||
|
|
||
| A benchmark fixture must: | ||
|
|
||
| * Measure a **single logical operation** per benchmark method. | ||
| * Avoid I/O, networking, disk access, logging, or side effects. | ||
| * Avoid expensive setup inside `[Benchmark]` methods. | ||
| * Use deterministic data (e.g., seeded RNG or predefined constants). | ||
| * Use `[GlobalSetup]` to allocate buffers, random payloads, or reusable test data only once. | ||
| * Avoid shared mutable state unless reset per iteration. | ||
|
|
||
| Use representative input sizes such as: | ||
|
|
||
| ```csharp | ||
| [Params(8, 256, 4096)] | ||
| public int Count { get; set; } | ||
| ``` | ||
|
|
||
| BenchmarkDotNet will run each benchmark for each parameter value. | ||
|
|
||
| --- | ||
|
|
||
| ## 4. Method Naming Conventions | ||
|
|
||
| Use descriptive names that communicate intent: | ||
|
|
||
| * `Parse_Short` | ||
| * `Parse_Long` | ||
| * `ComputeHash_Small` | ||
| * `ComputeHash_Large` | ||
| * `Serialize_Optimized` | ||
| * `Serialize_Baseline` | ||
|
|
||
| When comparing approaches, always list them clearly and tag one as the baseline. | ||
|
|
||
| --- | ||
|
|
||
| ## 5. Example Benchmark Fixture | ||
|
|
||
| ```csharp | ||
| using BenchmarkDotNet.Attributes; | ||
| using BenchmarkDotNet.Configs; | ||
|
|
||
| namespace YourProject | ||
| { | ||
| [MemoryDiagnoser] | ||
| [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] | ||
| public class SampleOperationBenchmark | ||
| { | ||
| [Params(8, 256, 4096)] | ||
| public int Count { get; set; } | ||
|
|
||
| private byte[] _payload; | ||
|
|
||
| [GlobalSetup] | ||
| public void Setup() | ||
| { | ||
| _payload = new byte[Count]; | ||
| // deterministic initialization | ||
| } | ||
|
|
||
| [Benchmark(Baseline = true, Description = "Operation - baseline")] | ||
| public int Operation_Baseline() => SampleOperation.Process(_payload); | ||
|
|
||
| [Benchmark(Description = "Operation - optimized")] | ||
| public int Operation_Optimized() => SampleOperation.ProcessOptimized(_payload); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 6. Reporting and CI | ||
|
|
||
| * Benchmark projects live exclusively under `tuning/`. They must not affect production builds. | ||
| * Heavy BenchmarkDotNet runs should *not* run in CI unless explicitly configured. | ||
| * Reports are produced by the benchmark runner and stored under the configured artifacts directory. | ||
|
|
||
| --- | ||
|
|
||
| ## 7. Additional Guidelines | ||
|
|
||
| * Keep benchmark fixtures focused and readable. | ||
| * Document non-obvious reasoning in short comments. | ||
| * Prefer realistic but deterministic data sets. | ||
| * When benchmarks reveal regressions or improvements, reference the associated PR or issue in a comment. | ||
| * Shared benchmark helpers belong in `tuning/` projects, not in production code. | ||
|
|
||
| --- | ||
|
|
||
| ## Final Notes | ||
|
|
||
| * Benchmarks are performance tests, not unit tests. | ||
| * Use `[Benchmark]` only for pure performance measurement. | ||
| * Avoid `MethodImplOptions.NoInlining` unless absolutely necessary. | ||
| * Use small sets of meaningful benchmark scenarios — avoid combinatorial explosion. |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| <Solution> | ||
| <Folder Name="/src/"> | ||
| <Project Path="src/Codebelt.Extensions.Globalization/Codebelt.Extensions.Globalization.csproj" /> | ||
| </Folder> | ||
| <Folder Name="/test/"> | ||
| <Project Path="test/Codebelt.Extensions.Globalization.Tests/Codebelt.Extensions.Globalization.Tests.csproj" /> | ||
| </Folder> | ||
| <Folder Name="/tooling/"> | ||
| <Project Path="tooling/gse/gse.csproj" /> | ||
| </Folder> | ||
| </Solution> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,10 +2,14 @@ | |||||||||||||||||
|
|
||||||||||||||||||
| <PropertyGroup> | ||||||||||||||||||
| <IsTestProject>$(MSBuildProjectName.EndsWith('Tests'))</IsTestProject> | ||||||||||||||||||
| <IsBenchmarkProject>$(MSBuildProjectName.EndsWith('Benchmarks'))</IsBenchmarkProject> | ||||||||||||||||||
| <IsSourceProject>$(MSBuildProjectDirectory.ToLower().StartsWith('$(MSBuildThisFileDirectory.ToLower())src'))</IsSourceProject> | ||||||||||||||||||
|
||||||||||||||||||
| <IsSourceProject>$(MSBuildProjectDirectory.ToLower().StartsWith('$(MSBuildThisFileDirectory.ToLower())src'))</IsSourceProject> | |
| <RootDirLower>$([MSBuild]::EnsureTrailingSlash('$(MSBuildThisFileDirectory)')).ToLower()</RootDirLower> | |
| <SrcRootLower>$(RootDirLower)src$([System.IO.Path]::DirectorySeparatorChar)</SrcRootLower> | |
| <IsSourceProject>$(MSBuildProjectDirectory.ToLower().StartsWith('$(SrcRootLower)'))</IsSourceProject> |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same path comparison issue exists for IsToolingProject. MSBuildThisFileDirectory may not include a trailing separator in all scenarios, which could cause the StartsWith check to fail or match incorrectly. Consider using a more robust path comparison or explicitly handling directory separators for cross-platform compatibility.
| <IsSourceProject>$(MSBuildProjectDirectory.ToLower().StartsWith('$(MSBuildThisFileDirectory.ToLower())src'))</IsSourceProject> | |
| <IsToolingProject>$(MSBuildProjectDirectory.ToLower().StartsWith('$(MSBuildThisFileDirectory.ToLower())tooling'))</IsToolingProject> | |
| <IsSourceProject>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)$(DirectorySeparatorChar)').ToLower().StartsWith($([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)src$(DirectorySeparatorChar)').ToLower()))</IsSourceProject> | |
| <IsToolingProject>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)$(DirectorySeparatorChar)').ToLower().StartsWith($([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)tooling$(DirectorySeparatorChar)').ToLower()))</IsToolingProject> |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The benchmark projects target netstandard2.0, which is unusual for benchmark projects. BenchmarkDotNet benchmarks are typically console applications that should target specific runtime frameworks (like net10.0 and net9.0) but not netstandard2.0, as netstandard2.0 is a specification for libraries, not executable applications. Consider removing netstandard2.0 from the TargetFrameworks list for benchmark projects.
| <TargetFrameworks>net10.0;net9.0;netstandard2.0</TargetFrameworks> | |
| <TargetFrameworks>net10.0;net9.0</TargetFrameworks> |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BenchmarkDotNet package references are missing version definitions in Directory.Packages.props. Since this project uses central package management (ManagePackageVersionsCentrally is set to true), all package versions must be defined in Directory.Packages.props. Add PackageVersion entries for both "BenchmarkDotNet" and "BenchmarkDotNet.Diagnostics.Windows" to Directory.Packages.props.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BenchmarkDotNet.Diagnostics.Windows is Windows-only.
This package provides Windows-specific diagnostics (ETW tracing, hardware counters via Windows Performance Counters). Including it unconditionally will cause restore failures or runtime issues on Linux/macOS builds. Consider conditionalizing this reference.
Proposed fix with platform condition
<ItemGroup Condition="'$(IsBenchmarkProject)' == 'true'">
<PackageReference Include="BenchmarkDotNet" />
- <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" />
+ <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Condition="'$(IsWindows)' == 'true'" />
</ItemGroup>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <ItemGroup Condition="'$(IsBenchmarkProject)' == 'true'"> | |
| <PackageReference Include="BenchmarkDotNet" /> | |
| <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" /> | |
| </ItemGroup> | |
| <ItemGroup Condition="'$(IsBenchmarkProject)' == 'true'"> | |
| <PackageReference Include="BenchmarkDotNet" /> | |
| <PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Condition="'$(IsWindows)' == 'true'" /> | |
| </ItemGroup> |
🤖 Prompt for AI Agents
In `@Directory.Build.props` around lines 115 - 118, The unconditional
PackageReference to BenchmarkDotNet.Diagnostics.Windows inside the ItemGroup for
IsBenchmarkProject causes cross-platform restore failures; modify the project
file so the PackageReference for BenchmarkDotNet.Diagnostics.Windows is only
included on Windows builds (e.g., add a Condition referencing the
OS/RuntimeIdentifier) while leaving BenchmarkDotNet unconditional. Locate the
ItemGroup with Condition "'$(IsBenchmarkProject)' == 'true'" and add a
platform-specific Condition to the PackageReference element named
BenchmarkDotNet.Diagnostics.Windows so non-Windows builds skip that package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix line ending characters.
Static analysis reports wrong line ending characters. The file uses CRLF (
\r\n) but the linter expects LF (\n). Ensure the file uses Unix-style line endings for consistency across the repository.🧰 Tools
🪛 YAMLlint (1.38.0)
[error] 1-1: wrong new line character: expected \n
(new-lines)
🤖 Prompt for AI Agents