Skip to content

Vectorize IA5 and Visible strings in ASN.1 encoding and decoding.#131109

Merged
vcsjones merged 3 commits into
dotnet:mainfrom
vcsjones:vector-asn1-string
Jul 21, 2026
Merged

Vectorize IA5 and Visible strings in ASN.1 encoding and decoding.#131109
vcsjones merged 3 commits into
dotnet:mainfrom
vcsjones:vector-asn1-string

Conversation

@vcsjones

Copy link
Copy Markdown
Member

This vectorizes the IA5Encoding and VisibleStringEncoding for ASN.1 encoding and decoding for the .NET implementations. Downlevel remains unchanged. Validation, encoding, and decoding will now operate on length of Vector<T> at a time instead of processing each input character-by-character or byte-by-byte.

Overall this shows good performance improvements. Allocations remain unchanged, and through improves for typical inputs. This only uses high-level System.Numerics Vector<T> - using intrinsics was not a goal of this change. This ensure we don't need to account for minor platform behavior differences.

For a 32 element input, decoding goes from 51.6ns to 17.7ns. Writing goes from 52.76ns to 21.06ns. Full benchmarks are available below the fold. Benchmark code is available at https://gist.github.com/vcsjones/73dbd0ae386b62a68b4d03cf71ed933d.

Error paths may be slightly slower. This is because we process data one vector of length at a time, including validation. However in the event of invalid input, we have to back up and process by scalar to find the exact position where the invalid element is to maintain exception compatibility. This feels like a worthy trade off, both because it's an error path and the exception throw and unwinding is still going to dominate, and for simplicity.

Some test cases were added to ensure all validation paths are correctly hit.

Performance

BenchmarkDotNet v0.15.8, macOS Tahoe 26.5.2 (25F84) [Darwin 25.5.0]
Apple M1 Ultra, 1 CPU, 20 logical and 20 physical cores
  [Host] : .NET 11.0.0 (11.0.0-dev, 42.42.42.42424), Arm64 RyuJIT armv8.0-a
  Main   : .NET 11.0.0 (11.0.0-dev, 42.42.42.42424), Arm64 RyuJIT armv8.0-a
  Vector : .NET 11.0.0 (11.0.0-dev, 42.42.42.42424), Arm64 RyuJIT armv8.0-a

Runtime=.NET 10.0  IterationCount=15  WarmupCount=5  

Type Method Job Toolchain Input Mean Error StdDev Ratio RatioSD Gen0 Gen1 Allocated Alloc Ratio
LongIa5Benchmarks Decode Main Main ? 1,400.90 ns 2.113 ns 1.873 ns 1.00 0.00 0.3300 - 2072 B 1.00
LongIa5Benchmarks Decode Vector Vector ? 226.35 ns 0.827 ns 0.691 ns 0.16 0.00 0.3302 - 2072 B 1.00
ShortIa5Benchmarks Decode Main Main ? 20.32 ns 0.027 ns 0.024 ns 1.00 0.00 0.0063 - 40 B 1.00
ShortIa5Benchmarks Decode Vector Vector ? 17.46 ns 0.044 ns 0.039 ns 0.86 0.00 0.0063 - 40 B 1.00
LongIa5Benchmarks Write Main Main ? 1,370.51 ns 6.418 ns 5.359 ns 1.00 0.01 0.1755 - 1104 B 1.00
LongIa5Benchmarks Write Vector Vector ? 265.40 ns 0.770 ns 0.720 ns 0.19 0.00 0.1760 - 1104 B 1.00
ShortIa5Benchmarks Write Main Main ? 23.36 ns 0.039 ns 0.037 ns 1.00 0.00 0.0140 - 88 B 1.00
ShortIa5Benchmarks Write Vector Vector ? 19.86 ns 0.046 ns 0.043 ns 0.85 0.00 0.0140 - 88 B 1.00
ValidIa5Benchmarks Decode Main Main DnsName 36.29 ns 0.081 ns 0.076 ns 1.00 0.00 0.0102 - 64 B 1.00
ValidIa5Benchmarks Decode Vector Vector DnsName 18.07 ns 0.040 ns 0.035 ns 0.50 0.00 0.0102 - 64 B 1.00
ValidIa5Benchmarks Write Main Main DnsName 37.34 ns 0.247 ns 0.219 ns 1.00 0.01 0.0153 - 96 B 1.00
ValidIa5Benchmarks Write Vector Vector DnsName 20.51 ns 0.230 ns 0.179 ns 0.55 0.01 0.0153 - 96 B 1.00
InvalidIa5Benchmarks DecodeInvalid Main Main EmailEarly 2,880.45 ns 4.989 ns 4.666 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks DecodeInvalid Vector Vector EmailEarly 2,885.77 ns 3.808 ns 3.562 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks WriteInvalid Main Main EmailEarly 1,182.06 ns 1.420 ns 1.259 ns 1.00 0.00 0.1163 - 736 B 1.00
InvalidIa5Benchmarks WriteInvalid Vector Vector EmailEarly 1,168.29 ns 1.759 ns 1.560 ns 0.99 0.00 0.1163 - 736 B 1.00
InvalidIa5Benchmarks DecodeInvalid Main Main EmailMiddle 2,886.74 ns 4.166 ns 3.693 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks DecodeInvalid Vector Vector EmailMiddle 2,876.05 ns 5.428 ns 5.078 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks WriteInvalid Main Main EmailMiddle 1,184.04 ns 1.944 ns 1.819 ns 1.00 0.00 0.1163 - 736 B 1.00
InvalidIa5Benchmarks WriteInvalid Vector Vector EmailMiddle 1,183.79 ns 1.825 ns 1.708 ns 1.00 0.00 0.1163 - 736 B 1.00
InvalidIa5Benchmarks DecodeInvalid Main Main EmailLate 2,888.25 ns 3.983 ns 3.531 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks DecodeInvalid Vector Vector EmailLate 2,879.34 ns 3.686 ns 3.268 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks WriteInvalid Main Main EmailLate 1,181.78 ns 1.037 ns 0.970 ns 1.00 0.00 0.1163 - 736 B 1.00
InvalidIa5Benchmarks WriteInvalid Vector Vector EmailLate 1,176.87 ns 2.646 ns 2.345 ns 1.00 0.00 0.1163 - 736 B 1.00
InvalidIa5Benchmarks DecodeInvalid Main Main Length256Late 3,060.51 ns 2.382 ns 2.111 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks DecodeInvalid Vector Vector Length256Late 2,928.94 ns 3.417 ns 3.197 ns 0.96 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks WriteInvalid Main Main Length256Late 1,362.22 ns 1.288 ns 1.205 ns 1.00 0.00 0.1564 - 984 B 1.00
InvalidIa5Benchmarks WriteInvalid Vector Vector Length256Late 1,223.28 ns 1.960 ns 1.833 ns 0.90 0.00 0.1564 - 984 B 1.00
InvalidIa5Benchmarks DecodeInvalid Main Main Length1024Late 3,558.98 ns 2.779 ns 2.600 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks DecodeInvalid Vector Vector Length1024Late 2,957.81 ns 2.656 ns 2.484 ns 0.83 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks WriteInvalid Main Main Length1024Late 1,888.57 ns 8.916 ns 7.904 ns 1.00 0.01 0.2785 - 1752 B 1.00
InvalidIa5Benchmarks WriteInvalid Vector Vector Length1024Late 1,326.31 ns 2.821 ns 2.639 ns 0.70 0.00 0.2785 - 1752 B 1.00
InvalidIa5Benchmarks DecodeInvalid Main Main Length4096Late 5,496.13 ns 6.284 ns 5.570 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks DecodeInvalid Vector Vector Length4096Late 3,119.58 ns 4.459 ns 3.952 ns 0.57 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks WriteInvalid Main Main Length4096Late 3,961.88 ns 7.917 ns 6.611 ns 1.00 0.00 0.7629 0.0076 4824 B 1.00
InvalidIa5Benchmarks WriteInvalid Vector Vector Length4096Late 1,740.70 ns 2.692 ns 2.519 ns 0.44 0.00 0.7668 0.0114 4824 B 1.00
VisibleStringBenchmarks Decode Main Main Length64 96.40 ns 0.116 ns 0.109 ns 1.00 0.00 0.0242 - 152 B 1.00
VisibleStringBenchmarks Decode Vector Vector Length64 24.41 ns 0.081 ns 0.068 ns 0.25 0.00 0.0242 - 152 B 1.00
VisibleStringBenchmarks Write Main Main Length64 101.00 ns 2.010 ns 1.880 ns 1.00 0.03 0.0229 - 144 B 1.00
VisibleStringBenchmarks Write Vector Vector Length64 28.27 ns 0.059 ns 0.055 ns 0.28 0.01 0.0229 - 144 B 1.00
VisibleStringBenchmarks Decode Main Main Length1024 1,386.68 ns 1.321 ns 1.171 ns 1.00 0.00 0.3300 - 2072 B 1.00
VisibleStringBenchmarks Decode Vector Vector Length1024 221.22 ns 0.353 ns 0.330 ns 0.16 0.00 0.3302 - 2072 B 1.00
VisibleStringBenchmarks Write Main Main Length1024 1,348.01 ns 1.441 ns 1.348 ns 1.00 0.00 0.1755 - 1104 B 1.00
VisibleStringBenchmarks Write Vector Vector Length1024 258.67 ns 0.799 ns 0.747 ns 0.19 0.00 0.1760 - 1104 B 1.00
InvalidIa5Benchmarks DecodeInvalid Main Main Length64Late 2,966.07 ns 5.094 ns 3.977 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks DecodeInvalid Vector Vector Length64Late 2,901.35 ns 4.689 ns 4.386 ns 0.98 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks WriteInvalid Main Main Length64Late 1,230.04 ns 2.293 ns 2.145 ns 1.00 0.00 0.1240 - 784 B 1.00
InvalidIa5Benchmarks WriteInvalid Vector Vector Length64Late 1,193.77 ns 1.603 ns 1.500 ns 0.97 0.00 0.1240 - 784 B 1.00
ValidIa5Benchmarks Decode Main Main ShortEmail 32.26 ns 0.060 ns 0.056 ns 1.00 0.00 0.0089 - 56 B 1.00
ValidIa5Benchmarks Decode Vector Vector ShortEmail 15.58 ns 0.055 ns 0.052 ns 0.48 0.00 0.0089 - 56 B 1.00
ValidIa5Benchmarks Write Main Main ShortEmail 34.38 ns 0.046 ns 0.043 ns 1.00 0.00 0.0153 - 96 B 1.00
ValidIa5Benchmarks Write Vector Vector ShortEmail 18.39 ns 0.120 ns 0.100 ns 0.53 0.00 0.0153 - 96 B 1.00
ValidIa5Benchmarks Decode Main Main LongEmail 85.55 ns 0.106 ns 0.099 ns 1.00 0.00 0.0216 - 136 B 1.00
ValidIa5Benchmarks Decode Vector Vector LongEmail 29.65 ns 0.068 ns 0.064 ns 0.35 0.00 0.0216 - 136 B 1.00
ValidIa5Benchmarks Write Main Main LongEmail 85.93 ns 0.120 ns 0.112 ns 1.00 0.00 0.0216 - 136 B 1.00
ValidIa5Benchmarks Write Vector Vector LongEmail 32.17 ns 0.109 ns 0.102 ns 0.37 0.00 0.0216 - 136 B 1.00
ValidIa5Benchmarks Decode Main Main Uri 92.23 ns 0.885 ns 0.784 ns 1.00 0.01 0.0242 - 152 B 1.00
ValidIa5Benchmarks Decode Vector Vector Uri 33.22 ns 0.060 ns 0.056 ns 0.36 0.00 0.0242 - 152 B 1.00
ValidIa5Benchmarks Write Main Main Uri 94.65 ns 0.060 ns 0.050 ns 1.00 0.00 0.0216 - 136 B 1.00
ValidIa5Benchmarks Write Vector Vector Uri 35.81 ns 0.071 ns 0.067 ns 0.38 0.00 0.0216 - 136 B 1.00
ValidIa5Benchmarks Decode Main Main Length8 20.08 ns 0.025 ns 0.024 ns 1.00 0.00 0.0063 - 40 B 1.00
ValidIa5Benchmarks Decode Vector Vector Length8 17.22 ns 0.029 ns 0.027 ns 0.86 0.00 0.0063 - 40 B 1.00
ValidIa5Benchmarks Write Main Main Length8 23.01 ns 0.048 ns 0.044 ns 1.00 0.00 0.0140 - 88 B 1.00
ValidIa5Benchmarks Write Vector Vector Length8 19.68 ns 0.038 ns 0.036 ns 0.86 0.00 0.0140 - 88 B 1.00
ValidIa5Benchmarks Decode Main Main Length16 30.80 ns 0.047 ns 0.044 ns 1.00 0.00 0.0089 - 56 B 1.00
ValidIa5Benchmarks Decode Vector Vector Length16 15.08 ns 0.135 ns 0.126 ns 0.49 0.00 0.0089 - 56 B 1.00
ValidIa5Benchmarks Write Main Main Length16 32.43 ns 0.054 ns 0.050 ns 1.00 0.00 0.0153 - 96 B 1.00
ValidIa5Benchmarks Write Vector Vector Length16 17.36 ns 0.045 ns 0.042 ns 0.54 0.00 0.0153 - 96 B 1.00
ValidIa5Benchmarks Decode Main Main Length32 51.66 ns 0.082 ns 0.077 ns 1.00 0.00 0.0140 - 88 B 1.00
ValidIa5Benchmarks Decode Vector Vector Length32 17.70 ns 0.068 ns 0.061 ns 0.34 0.00 0.0140 - 88 B 1.00
ValidIa5Benchmarks Write Main Main Length32 52.76 ns 0.074 ns 0.069 ns 1.00 0.00 0.0178 - 112 B 1.00
ValidIa5Benchmarks Write Vector Vector Length32 21.06 ns 0.079 ns 0.062 ns 0.40 0.00 0.0179 - 112 B 1.00
ValidIa5Benchmarks Decode Main Main Length64 96.62 ns 0.143 ns 0.134 ns 1.00 0.00 0.0242 - 152 B 1.00
ValidIa5Benchmarks Decode Vector Vector Length64 24.60 ns 0.115 ns 0.096 ns 0.25 0.00 0.0242 - 152 B 1.00
ValidIa5Benchmarks Write Main Main Length64 106.81 ns 0.158 ns 0.140 ns 1.00 0.00 0.0229 - 144 B 1.00
ValidIa5Benchmarks Write Vector Vector Length64 28.05 ns 0.050 ns 0.047 ns 0.26 0.00 0.0229 - 144 B 1.00
ValidIa5Benchmarks Decode Main Main Length128 195.11 ns 0.174 ns 0.155 ns 1.00 0.00 0.0446 - 280 B 1.00
ValidIa5Benchmarks Decode Vector Vector Length128 38.80 ns 0.120 ns 0.112 ns 0.20 0.00 0.0446 - 280 B 1.00
ValidIa5Benchmarks Write Main Main Length128 196.89 ns 0.083 ns 0.073 ns 1.00 0.00 0.0331 - 208 B 1.00
ValidIa5Benchmarks Write Vector Vector Length128 43.85 ns 0.104 ns 0.087 ns 0.22 0.00 0.0331 - 208 B 1.00
ValidIa5Benchmarks Decode Main Main Length256 367.03 ns 0.271 ns 0.240 ns 1.00 0.00 0.0854 - 536 B 1.00
ValidIa5Benchmarks Decode Vector Vector Length256 64.32 ns 0.209 ns 0.195 ns 0.18 0.00 0.0854 - 536 B 1.00
ValidIa5Benchmarks Write Main Main Length256 359.23 ns 0.373 ns 0.348 ns 1.00 0.00 0.0534 - 336 B 1.00
ValidIa5Benchmarks Write Vector Vector Length256 73.64 ns 0.117 ns 0.104 ns 0.20 0.00 0.0535 - 336 B 1.00
ValidIa5Benchmarks Decode Main Main Length1024 1,389.09 ns 12.097 ns 10.724 ns 1.00 0.01 0.3300 - 2072 B 1.00
ValidIa5Benchmarks Decode Vector Vector Length1024 222.03 ns 0.713 ns 0.557 ns 0.16 0.00 0.3302 - 2072 B 1.00
ValidIa5Benchmarks Write Main Main Length1024 1,350.11 ns 1.211 ns 1.073 ns 1.00 0.00 0.1755 - 1104 B 1.00
ValidIa5Benchmarks Write Vector Vector Length1024 253.19 ns 0.493 ns 0.461 ns 0.19 0.00 0.1760 - 1104 B 1.00
ValidIa5Benchmarks Decode Main Main Length4096 5,436.07 ns 6.509 ns 6.088 ns 1.00 0.00 1.3046 - 8216 B 1.00
ValidIa5Benchmarks Decode Vector Vector Length4096 863.95 ns 1.696 ns 1.324 ns 0.16 0.00 1.3084 - 8216 B 1.00
ValidIa5Benchmarks Write Main Main Length4096 5,328.17 ns 5.326 ns 4.982 ns 1.00 0.00 0.6638 0.0076 4176 B 1.00
ValidIa5Benchmarks Write Vector Vector Length4096 1,000.79 ns 1.553 ns 1.453 ns 0.19 0.00 0.6657 0.0095 4176 B 1.00
InvalidIa5Benchmarks DecodeInvalid Main Main LongEmailLate 2,933.39 ns 13.165 ns 11.671 ns 1.00 0.01 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks DecodeInvalid Vector Vector LongEmailLate 2,918.78 ns 5.534 ns 4.321 ns 1.00 0.00 0.1984 - 1264 B 1.00
InvalidIa5Benchmarks WriteInvalid Main Main LongEmailLate 1,232.75 ns 8.312 ns 7.369 ns 1.00 0.01 0.1221 - 776 B 1.00
InvalidIa5Benchmarks WriteInvalid Vector Vector LongEmailLate 1,194.64 ns 5.756 ns 5.103 ns 0.97 0.01 0.1221 - 776 B 1.00
VisibleStringBenchmarks Decode Main Main ShortText 24.09 ns 0.029 ns 0.026 ns 1.00 0.00 0.0076 - 48 B 1.00
VisibleStringBenchmarks Decode Vector Vector ShortText 19.82 ns 0.027 ns 0.025 ns 0.82 0.00 0.0076 - 48 B 1.00
VisibleStringBenchmarks Write Main Main ShortText 26.24 ns 0.038 ns 0.033 ns 1.00 0.00 0.0140 - 88 B 1.00
VisibleStringBenchmarks Write Vector Vector ShortText 21.92 ns 0.047 ns 0.042 ns 0.84 0.00 0.0140 - 88 B 1.00
VisibleStringBenchmarks Decode Main Main Uri 95.28 ns 0.210 ns 0.197 ns 1.00 0.00 0.0242 - 152 B 1.00
VisibleStringBenchmarks Decode Vector Vector Uri 33.43 ns 0.084 ns 0.079 ns 0.35 0.00 0.0242 - 152 B 1.00
VisibleStringBenchmarks Write Main Main Uri 94.32 ns 0.072 ns 0.068 ns 1.00 0.00 0.0216 - 136 B 1.00
VisibleStringBenchmarks Write Vector Vector Uri 35.50 ns 0.070 ns 0.065 ns 0.38 0.00 0.0216 - 136 B 1.00

This vectorizes the IA5Encoding and VisibleStringEncoding for ASN.1 encoding and decoding.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@vcsjones

Copy link
Copy Markdown
Member Author

/cc @tannergooding since this is adjacent to your wheelhouse.

@vcsjones

Copy link
Copy Markdown
Member Author

cc @dotnet/area-system-formats-asn1

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-formats-asn1, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

@vcsjones vcsjones added the tenet-performance Performance related issue label Jul 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 improves System.Formats.Asn1 character-string handling by introducing a vectorized fast-path for IA5String and VisibleString encoding/decoding on .NET (while keeping downlevel behavior unchanged), and extends tests to cover vector-width boundaries and invalid-data index reporting.

Changes:

  • Introduces RestrictedAsciiRangeEncoding for .NETCoreApp builds, using System.Numerics.Vector<T> to validate/convert in vector-sized chunks with scalar fallback to preserve exception-index behavior.
  • Switches IA5Encoding and VisibleStringEncoding to derive from RestrictedAsciiRangeEncoding (range-based validation) instead of the existing allowed-table implementation.
  • Adds targeted reader/writer tests for vector-sized payloads and “invalid after vector prefix” scenarios.
Show a summary per file
File Description
src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.net.cs Adds vectorized range-based encoding/decoding implementation for IA5/VisibleString on .NET.
src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.downlevel.cs Keeps downlevel behavior by mapping RestrictedAsciiRangeEncoding to the existing restricted ASCII encoder.
src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.cs Updates IA5/VisibleString encodings to use the new range-based base type.
src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csproj Adds conditional compile includes for the new files and references System.Numerics.Vectors for .NET builds.
src/libraries/System.Formats.Asn1/tests/Writer/WriteIA5String.cs Adds an invalid IA5 input with an invalid character after a vector-sized prefix.
src/libraries/System.Formats.Asn1/tests/Writer/SimpleWriterTests.cs Adds VisibleString writer tests for vector-sized payloads and invalid character index reporting.
src/libraries/System.Formats.Asn1/tests/Reader/ReadIA5String.cs Adds IA5 reader coverage for a longer valid input and a vector-prefix invalid input case.
src/libraries/System.Formats.Asn1/tests/Reader/ComprehensiveReadTests.cs Adds VisibleString reader tests for vector-sized payloads and invalid byte index reporting.

Copilot's findings

  • Files reviewed: 8/8 changed files
  • Comments generated: 1

@tannergooding
tannergooding self-requested a review July 20, 2026 22:35
@tannergooding

tannergooding commented Jul 20, 2026

Copy link
Copy Markdown
Member

Should be able to get to this later tonight. At a high level glance it generally looks good/correct and following all the guidance.

I notably did just get a rewrite of the public SIMD (on docs.microsoft.com) done and have a PR up adding a vectorization skill for review/authoring, so if you're up for it then it might be a good first trial of it (not merged yet): #131108

@bartonjs

Copy link
Copy Markdown
Member

Generally looks good to me, nothing stood out in review (though I didn't stop and think hard about the bounds). Have the benchmarks been run against strings at various offsets, just making sure alignment isn't a problem.

Since one of the tests clearly is operating at alignment+3, I'm going to guess it's all good, but it still feels like something worth checking.

@vcsjones

Copy link
Copy Markdown
Member Author

Have the benchmarks been run against strings at various offsets, just making sure alignment isn't a problem.

Seems fine and still significant performance gains. Results (too big for a GH comment): https://gist.github.com/vcsjones/6500b884c3f145f0c3fb11749dbf566c

@tannergooding tannergooding left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

I also tested this locally against the new vectorization skill and depending on model the feedback was generally along the lines of:

  1. You might be able to add a fast path to reuse Ascii.IsValid for the cases the range is "all ascii"
  2. This is using Vector<T> rather than the fixed-width vectors and so may leave perf on the table
  3. No explicit tests using BoundedMemory were added to help ensure safety

None of those I view as "blocking", particularly given the area and the way the code is setup.

Copilot AI review requested due to automatic review settings July 21, 2026 15:48
@vcsjones

Copy link
Copy Markdown
Member Author

You might be able to add a fast path to reuse Ascii.IsValid for the cases the range is "all ascii"

This is using Vector rather than the fixed-width vectors and so may leave perf on the table

I think the code reuse between IA5String and VisibleString is more valuable. Neither I don't think are quite used enough to warrant intense optimization to eke out every ounce of performance.

No explicit tests using BoundedMemory were added to help ensure safety

My impression was that Vector<T> is "high level" enough that it should on its own have bounds checking that does the right thing, but adding bounded memory tests is easy enough and I needed to fix a typo, so done.

@tannergooding

Copy link
Copy Markdown
Member

My impression was that Vector is "high level" enough that it should on its own have bounds checking that does the right thing, but adding bounded memory tests is easy enough and I needed to fix a typo, so done.

It should be, especially if you use the Create(Span<T>) APIs instead of Load/LoadUnsafe. But it's also one of the cases that can often just integrate naturally into the edges you should already be testing (and which in your case you already were covering) so the guidance is kept as just general guidance.

Like I said, I didn't personally view any of that as blocking, more just "automatic callouts" that vectorization PRs may get from Copilot in the future (which will likely always be a bit stricter than a human reviewer).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

Comments suppressed due to low confidence (1)

src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.net.cs:154

  • Same as above: the comment says it returns the position "before the current vector's width", but the code returns the current position. Please align the comment with the actual behavior.
                    // If any element in the vector is not allowed, we break out and return the position before the
                    // current vector's width so that it goes down the scalar path. The scalar path will determine the
                    // precise location of the invalid element.
  • Files reviewed: 8/8 changed files
  • Comments generated: 1

@vcsjones
vcsjones enabled auto-merge (squash) July 21, 2026 16:31
@vcsjones
vcsjones merged commit 2d21ab7 into dotnet:main Jul 21, 2026
83 checks passed
@vcsjones
vcsjones deleted the vector-asn1-string branch July 21, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants