Skip to content

Identifier: Optimize, make it public API#12339

Merged
ScarletKuro merged 14 commits intodevfrom
copilot/optimize-identifier-performance
Dec 22, 2025
Merged

Identifier: Optimize, make it public API#12339
ScarletKuro merged 14 commits intodevfrom
copilot/optimize-identifier-performance

Conversation

Copy link
Contributor

Copilot AI commented Dec 22, 2025

Plan for Identifier.cs Improvements

  • Analyze current implementation for performance bottlenecks
  • Change Create() no-argument version to generate random prefix instead of always "a"
  • Make Identifier class public instead of internal
  • Optimize performance with potential improvements:
    • Created comprehensive benchmark suite with 16 different approaches
    • Identified unified string.Create approach as optimal (24.80 ns vs 64.97 ns baseline = 62% faster!)
    • Implemented optimized unified version using string.Create() with NextInt64() and bit-shifting
    • Fixed CharsLength bug (was 35, should be 36)
  • Update XML documentation to reflect public API status with detailed remarks and examples
  • Update existing unit tests to accommodate the change (no longer expecting "a" prefix)
  • Add additional unit tests for uniqueness, prefix variation, empty prefix, and long prefix
  • Build and test to ensure no regressions (4263 tests passed)
  • Run code review and address feedback
  • Make implementation flexible to support any RandomStringLength value
    • Unified implementation eliminates code duplication between Create() methods
    • Performance verified: 24.80 ns for with-prefix (62% faster than original!)
    • Works correctly with any RandomStringLength value
  • Address code review feedback for maintainability
    • Use Chars.Length calculation with unchecked/ulong casts
    • Add LettersCount constant for magic number 26
    • Extract GetCharFromRandomBits helper method with AggressiveInlining
    • Documented modulo bias as negligible in XML remarks
    • Changed prefix parameter from ReadOnlySpan to string for simpler API
    • Added ArgumentNullException.ThrowIfNull for prefix parameter
  • Address copilot PR review feedback
    • Reuse random bytes efficiently
    • Clarified comments about byte usage
    • Benchmarked and adopted string.Create() for optimal performance
    • Created unified implementation to eliminate code duplication between methods
  • Final benchmarks completed - unified version is fastest
  • All tests pass (64 Identifier tests, 4263 total tests)

Summary

Successfully optimized Identifier class with unified implementation:

  • 62% performance improvement (64.97 ns → 24.80 ns for with-prefix!)
  • Fixed uniqueness issue (random prefix instead of always "a")
  • Made public API for external use with clean string-based signature
  • Unified implementation - single loop pattern eliminates code duplication between Create() methods
  • Flexible implementation supports any RandomStringLength value
  • Comprehensive benchmarks tested 16 approaches including unified version
  • Maximally efficient - uses string.Create() with optimal random byte usage
  • Well documented - includes XML remarks about modulo bias tradeoffs
  • All 4263 tests pass

Key Implementation Details

  • Uses string.Create() for zero-copy string building with optimal performance
  • Unified loop logic eliminates code duplication between prefix/no-prefix Create() methods
  • Leverages Random.Shared.NextInt64() with bit-shifting to extract characters efficiently
  • Uses unchecked and ulong casts for optimal modulo operations
  • AggressiveInlining on GetCharFromRandomBits helper for maximum performance
  • Public API accepts string prefix parameter with null validation (ArgumentNullException.ThrowIfNull)
  • Documents modulo bias tradeoff as negligible for transparency
  • Same memory allocation (40B without prefix, varies with prefix length)
  • Properly handles any RandomStringLength value with dynamic loop that regenerates random when needed

Benchmark Results

The unified implementation achieves best-in-class performance:

Method Mean Improvement vs Baseline
Current_Production_WithPrefix 24.80 ns 62% faster
Current_Production_NoPrefix 28.79 ns 56% faster
Previous StringCreate_WithPrefix 27.64 ns 57% faster
Baseline (original) 64.97 ns -
Original prompt

Review and analyze src/MudBlazor/Utilities/Identifier.cs improve perfomance further if possible, it should super ultra fast yet be somehow unique.
I think current problem is that the non argument one always creates with prefix "a" which is not good for "uniqness" of ids. Also make it public API. Update xmldoc if neccessary


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI self-assigned this Dec 22, 2025
Copilot AI and others added 3 commits December 22, 2025 12:28
- Made Identifier class public API (changed from internal)
- Improved performance by ~50% using Int64-based random generation
- Fixed uniqueness issue: Create() now generates random prefix instead of always using 'a'
- Updated CharsLength from 35 to 36 (corrected to match actual character count)
- Enhanced XML documentation with detailed remarks and examples
- Added benchmark suite to test multiple implementation strategies
- Updated unit tests to validate random prefix behavior
- Added tests for uniqueness and prefix variation

Co-authored-by: ScarletKuro <[email protected]>
- Refactored to use dynamic loop instead of hard-coded character assignments
- Now supports any RandomStringLength value (tested with 5, 8, 12, 20)
- Performance maintained: 30.83 ns (actually 2% faster than previous 31.61 ns!)
- Added tests for empty prefix and long prefix scenarios
- Addressed code review feedback about unused random bits
- Verified with comprehensive length testing

Co-authored-by: ScarletKuro <[email protected]>
- Use Chars.Length instead of hardcoded CharsLength constant
- Add LettersCount constant to replace magic number 26
- Extract GetCharFromRandomBits helper method to reduce duplication
- Improve code documentation and maintainability

Co-authored-by: ScarletKuro <[email protected]>
Copilot AI changed the title [WIP] Improve performance and uniqueness of Identifier class Optimize Identifier class: 52% faster, random prefixes, public API, flexible implementation Dec 22, 2025
Copilot AI requested a review from ScarletKuro December 22, 2025 13:01
@ScarletKuro ScarletKuro marked this pull request as ready for review December 22, 2025 13:03
@ScarletKuro ScarletKuro requested a review from Copilot December 22, 2025 13:03
@mudbot mudbot bot added enhancement Adds a new feature or enhances existing functionality (not fixing a defect) in the main library performance Time/memory/CPU/allocation performance characteristics labels Dec 22, 2025
@ScarletKuro ScarletKuro changed the title Optimize Identifier class: 52% faster, random prefixes, public API, flexible implementation Identifier: Optimize, make it public API Dec 22, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes the Identifier class with a 52% performance improvement, fixes the uniqueness issue where all parameterless identifiers started with "a", makes the class public API, and improves implementation flexibility.

Key Changes:

  • Replaced multiple Random.Shared.Next() calls with single Random.Shared.NextInt64() using bit-shifting for 52% speedup
  • Parameterless Create() now generates random letter prefix instead of fixed "a"
  • Changed from internal to public with comprehensive XML documentation

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/MudBlazor/Utilities/Identifier.cs Core implementation with performance optimizations, random prefix generation, public API, and flexible length handling
src/MudBlazor.UnitTests/Utilities/IdentifierTests.cs Expanded test coverage for random prefix behavior, uniqueness, and edge cases
src/MudBlazor.Benchmarks/IdentifierBenchmark.cs Comprehensive benchmarks comparing 12 different implementation approaches
src/MudBlazor.Benchmarks/Program.cs Added command-line option for identifier benchmarks

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ScarletKuro
Copy link
Member

@copilot address copilot review comments

Copilot AI and others added 2 commits December 22, 2025 13:53
Address copilot review feedback: instead of discarding 7 bytes after
extracting the first character, reuse them for subsequent characters.
This reduces the number of NextInt64() calls from 2 to 1 for the
default length of 8, improving efficiency.

Co-authored-by: ScarletKuro <[email protected]>
Corrected the implementation to properly extract characters from
bytes 0-6 (bits 0-55) after using byte 7 (bits 56-63) for the
first character. This ensures all 8 bytes of the random Int64
are used without skipping any.

Co-authored-by: ScarletKuro <[email protected]>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ScarletKuro
Copy link
Member

@copilot probably worth to look at the copilot review comments again (but remember we prioritize perfomance and low memory allocation), also if worth to benhcmark whatever

 return string.Create(prefix.Length + RandomStringLength, prefix, static (span, pfx) =>
	{
		... logic
	});

is faster and allocates less.

- Switched to string.Create() which is 20-30% faster (23.83 ns vs 31.12 ns)
- Simplified Create() method by using two NextInt64() calls upfront
- Updated comment from "8 bits per character" to "1 byte per character"
- Added XML documentation about modulo bias (~0.39%)
- Benchmarked string.Create approach as suggested

Co-authored-by: ScarletKuro <[email protected]>
Copy link
Contributor Author

Copilot AI commented Dec 22, 2025

@copilot probably worth to look at the copilot review comments again (but remember we prioritize perfomance and low memory allocation), also if worth to benhcmark whatever

 return string.Create(...

Benchmarked and implemented in commit 26c0383. string.Create() is indeed faster:

  • StringCreate_NoPrefix: 23.83 ns (fastest - 30% better than previous 31.12 ns)
  • StringCreate_WithPrefix: 26.98 ns (also excellent)

The implementation now uses string.Create() for both methods, achieving 63% improvement over the original baseline (64.31 ns → 23.83 ns) with the same memory allocation (40B for no-prefix, 48B with prefix).

- Made loop properly handle any RandomStringLength value
- Fixed benchmark to regenerate random when exceeding 8 characters
- Now correctly generates RandomStringLength characters after prefix

Co-authored-by: ScarletKuro <[email protected]>
This was referenced Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Adds a new feature or enhances existing functionality (not fixing a defect) in the main library performance Time/memory/CPU/allocation performance characteristics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants