Skip to content

Conversation

@EgorBo
Copy link
Member

@EgorBo EgorBo commented Oct 23, 2025

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..

@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

@stephentoub
Copy link
Member

(When I previously experimented with this it was quite measurable, but maybe things have improved since then.)

@EgorBo

This comment was marked as resolved.

@EgorBo
Copy link
Member Author

EgorBo commented Oct 27, 2025

@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);
}

@EgorBo EgorBo marked this pull request as ready for review October 27, 2025 18:11
Copilot AI review requested due to automatic review settings October 27, 2025 18:11
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 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 unsafe keyword and pointer parameters from TestForSubPath and UnescapePercentEncodedUTF8Sequence methods
  • 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 TestForSubPath from unsafe pointer-based to span-based implementation; updated call to UnescapePercentEncodedUTF8Sequence
UriExt.cs Removed unsafe block and fixed statements in IsBaseOfHelper, now directly passes strings to TestForSubPath
PercentEncodingHelper.cs Converted UnescapePercentEncodedUTF8Sequence signature from pointer to span; replaced pointer arithmetic with span slicing
IriHelper.cs Updated call site to pass ReadOnlySpan<char> instead of pointer to UnescapePercentEncodedUTF8Sequence

@EgorBo
Copy link
Member Author

EgorBo commented Oct 27, 2025

@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 Perf_Uri benchmark suit here - still no regressions.
+36 bytes codegen overhead in jit-diffs.

@stephentoub
Copy link
Member

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)

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)

@EgorBo
Copy link
Member Author

EgorBo commented Oct 28, 2025

/ba-g deadletter

@EgorBo EgorBo merged commit da2e367 into dotnet:main Oct 28, 2025
84 of 86 checks passed
@EgorBo EgorBo deleted the safe-ipaddress branch October 28, 2025 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants