- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.2k
Convert pointers to span in System.Net.Primitives #121016
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
Conversation
| Tagging subscribers to this area: @dotnet/ncl | 
| (When I previously experimented with this it was quite measurable, but maybe things have improved since then.) | 
d7aebf1    to
    4b7bc1b      
    Compare
  
    
      
        
              This comment was marked as resolved.
        
        
      
    
  This comment was marked as resolved.
4b7bc1b    to
    3aca4e7      
    Compare
  
    | @EgorBot -intel -arm -amd using BenchmarkDotNet.Attributes;
public class UriParsingBenchmarks
{
    public static IEnumerable<string> GetTestData() => new[]
    {
        "https://alice:pa%24%24@例子.com/テスト",
        "https://bob%40dev:%F0%9F%92%[email protected]/💾/ファイル",
        "https://user:pwd%40key@пример.тест/данные/測試?mode=%E6%A4%9C%E8%A8%BC",
        "https://user:pa%24%[email protected]/路径/данные/資料",
        "https://data:tok3n@服务.cn/文件/📊/統計?state=%7B%22ok%22%3Atrue%2C%22v%22%3A%22%25done%25%22%7D",
        "https://token%3Auser:secr%25et@ドメイン.example/分析/データ/данные",
        "https://üser:päss@пример.com/страница/テスト?lang=日本語",
        "https://john:doe%21pass@δοκιμή.gr/δοκιμή/資料?ref=abc%25xyz",
        "https://账号:密码@例え.テスト/画像/файлы?タグ=猫%20写真",
        "https://x:y%25z@データ.jp/経路/данные/🧠/研究?city=Z%C3%BCrich&lang=%E6%97%A5%E6%9C%AC%E8%AA%9E"
    };
    // Baseline: construct a Uri
    [Benchmark(Baseline = true)]
    [ArgumentsSource(nameof(GetTestData))]
    public Uri NewUri(string uri) => new (uri);
} | 
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.
Pull Request Overview
This PR converts pointer-based string operations to ReadOnlySpan<char> in the System.Private.Uri library to improve code safety and make bounds checking more explicit. The change addresses concerns about raw pointer arithmetic that makes it difficult to validate array access safety.
Key Changes:
- Removed unsafekeyword and pointer parameters fromTestForSubPathandUnescapePercentEncodedUTF8Sequencemethods
- Replaced pointer arithmetic with span indexing and slicing operations
- Updated call sites to pass spans instead of fixed pointers
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description | 
|---|---|
| UriHelper.cs | Converted TestForSubPathfrom unsafe pointer-based to span-based implementation; updated call toUnescapePercentEncodedUTF8Sequence | 
| UriExt.cs | Removed unsafeblock andfixedstatements inIsBaseOfHelper, now directly passes strings toTestForSubPath | 
| PercentEncodingHelper.cs | Converted UnescapePercentEncodedUTF8Sequencesignature from pointer to span; replaced pointer arithmetic with span slicing | 
| IriHelper.cs | Updated call site to pass ReadOnlySpan<char>instead of pointer toUnescapePercentEncodedUTF8Sequence | 
        
          
                src/libraries/System.Private.Uri/src/System/PercentEncodingHelper.cs
              
                Outdated
          
            Show resolved
            Hide resolved
        
      | @stephentoub @MihaZupan I've limited changes to Iri parsing and it seems like my benchmarks (which utilize the code that I changed) didn't regress (-/+2% noise). Unless I'm missing something. I also ran  | 
| 
 For reference, my comment about having previously tested it and having seen regressions were about the IPAddress changes that were in the original commit (d7aebf1) | 
Co-authored-by: Stephen Toub <[email protected]>
| /ba-g deadletter | 
IPAddress and Uri parsing are heavily relying on raw pointers making code extremely difficult to validate we never go out of bounds. I wonder what is the performance impact if we convert them all to Span.. Obviously, in most cases it will lead to redundant bounds checks that JIT is unlikely to remove due to complex loop shapes, implicit/IPA assumptions, etc..