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.NumericsVector<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 
TypeMethodJobToolchainInputMeanErrorStdDevRatioRatioSDGen0Gen1AllocatedAlloc Ratio
LongIa5BenchmarksDecodeMainMain?1,400.90 ns2.113 ns1.873 ns1.000.000.3300-2072 B1.00
LongIa5BenchmarksDecodeVectorVector?226.35 ns0.827 ns0.691 ns0.160.000.3302-2072 B1.00
ShortIa5BenchmarksDecodeMainMain?20.32 ns0.027 ns0.024 ns1.000.000.0063-40 B1.00
ShortIa5BenchmarksDecodeVectorVector?17.46 ns0.044 ns0.039 ns0.860.000.0063-40 B1.00
LongIa5BenchmarksWriteMainMain?1,370.51 ns6.418 ns5.359 ns1.000.010.1755-1104 B1.00
LongIa5BenchmarksWriteVectorVector?265.40 ns0.770 ns0.720 ns0.190.000.1760-1104 B1.00
ShortIa5BenchmarksWriteMainMain?23.36 ns0.039 ns0.037 ns1.000.000.0140-88 B1.00
ShortIa5BenchmarksWriteVectorVector?19.86 ns0.046 ns0.043 ns0.850.000.0140-88 B1.00
ValidIa5BenchmarksDecodeMainMainDnsName36.29 ns0.081 ns0.076 ns1.000.000.0102-64 B1.00
ValidIa5BenchmarksDecodeVectorVectorDnsName18.07 ns0.040 ns0.035 ns0.500.000.0102-64 B1.00
ValidIa5BenchmarksWriteMainMainDnsName37.34 ns0.247 ns0.219 ns1.000.010.0153-96 B1.00
ValidIa5BenchmarksWriteVectorVectorDnsName20.51 ns0.230 ns0.179 ns0.550.010.0153-96 B1.00
InvalidIa5BenchmarksDecodeInvalidMainMainEmailEarly2,880.45 ns4.989 ns4.666 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksDecodeInvalidVectorVectorEmailEarly2,885.77 ns3.808 ns3.562 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksWriteInvalidMainMainEmailEarly1,182.06 ns1.420 ns1.259 ns1.000.000.1163-736 B1.00
InvalidIa5BenchmarksWriteInvalidVectorVectorEmailEarly1,168.29 ns1.759 ns1.560 ns0.990.000.1163-736 B1.00
InvalidIa5BenchmarksDecodeInvalidMainMainEmailMiddle2,886.74 ns4.166 ns3.693 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksDecodeInvalidVectorVectorEmailMiddle2,876.05 ns5.428 ns5.078 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksWriteInvalidMainMainEmailMiddle1,184.04 ns1.944 ns1.819 ns1.000.000.1163-736 B1.00
InvalidIa5BenchmarksWriteInvalidVectorVectorEmailMiddle1,183.79 ns1.825 ns1.708 ns1.000.000.1163-736 B1.00
InvalidIa5BenchmarksDecodeInvalidMainMainEmailLate2,888.25 ns3.983 ns3.531 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksDecodeInvalidVectorVectorEmailLate2,879.34 ns3.686 ns3.268 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksWriteInvalidMainMainEmailLate1,181.78 ns1.037 ns0.970 ns1.000.000.1163-736 B1.00
InvalidIa5BenchmarksWriteInvalidVectorVectorEmailLate1,176.87 ns2.646 ns2.345 ns1.000.000.1163-736 B1.00
InvalidIa5BenchmarksDecodeInvalidMainMainLength256Late3,060.51 ns2.382 ns2.111 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksDecodeInvalidVectorVectorLength256Late2,928.94 ns3.417 ns3.197 ns0.960.000.1984-1264 B1.00
InvalidIa5BenchmarksWriteInvalidMainMainLength256Late1,362.22 ns1.288 ns1.205 ns1.000.000.1564-984 B1.00
InvalidIa5BenchmarksWriteInvalidVectorVectorLength256Late1,223.28 ns1.960 ns1.833 ns0.900.000.1564-984 B1.00
InvalidIa5BenchmarksDecodeInvalidMainMainLength1024Late3,558.98 ns2.779 ns2.600 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksDecodeInvalidVectorVectorLength1024Late2,957.81 ns2.656 ns2.484 ns0.830.000.1984-1264 B1.00
InvalidIa5BenchmarksWriteInvalidMainMainLength1024Late1,888.57 ns8.916 ns7.904 ns1.000.010.2785-1752 B1.00
InvalidIa5BenchmarksWriteInvalidVectorVectorLength1024Late1,326.31 ns2.821 ns2.639 ns0.700.000.2785-1752 B1.00
InvalidIa5BenchmarksDecodeInvalidMainMainLength4096Late5,496.13 ns6.284 ns5.570 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksDecodeInvalidVectorVectorLength4096Late3,119.58 ns4.459 ns3.952 ns0.570.000.1984-1264 B1.00
InvalidIa5BenchmarksWriteInvalidMainMainLength4096Late3,961.88 ns7.917 ns6.611 ns1.000.000.76290.00764824 B1.00
InvalidIa5BenchmarksWriteInvalidVectorVectorLength4096Late1,740.70 ns2.692 ns2.519 ns0.440.000.76680.01144824 B1.00
VisibleStringBenchmarksDecodeMainMainLength6496.40 ns0.116 ns0.109 ns1.000.000.0242-152 B1.00
VisibleStringBenchmarksDecodeVectorVectorLength6424.41 ns0.081 ns0.068 ns0.250.000.0242-152 B1.00
VisibleStringBenchmarksWriteMainMainLength64101.00 ns2.010 ns1.880 ns1.000.030.0229-144 B1.00
VisibleStringBenchmarksWriteVectorVectorLength6428.27 ns0.059 ns0.055 ns0.280.010.0229-144 B1.00
VisibleStringBenchmarksDecodeMainMainLength10241,386.68 ns1.321 ns1.171 ns1.000.000.3300-2072 B1.00
VisibleStringBenchmarksDecodeVectorVectorLength1024221.22 ns0.353 ns0.330 ns0.160.000.3302-2072 B1.00
VisibleStringBenchmarksWriteMainMainLength10241,348.01 ns1.441 ns1.348 ns1.000.000.1755-1104 B1.00
VisibleStringBenchmarksWriteVectorVectorLength1024258.67 ns0.799 ns0.747 ns0.190.000.1760-1104 B1.00
InvalidIa5BenchmarksDecodeInvalidMainMainLength64Late2,966.07 ns5.094 ns3.977 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksDecodeInvalidVectorVectorLength64Late2,901.35 ns4.689 ns4.386 ns0.980.000.1984-1264 B1.00
InvalidIa5BenchmarksWriteInvalidMainMainLength64Late1,230.04 ns2.293 ns2.145 ns1.000.000.1240-784 B1.00
InvalidIa5BenchmarksWriteInvalidVectorVectorLength64Late1,193.77 ns1.603 ns1.500 ns0.970.000.1240-784 B1.00
ValidIa5BenchmarksDecodeMainMainShortEmail32.26 ns0.060 ns0.056 ns1.000.000.0089-56 B1.00
ValidIa5BenchmarksDecodeVectorVectorShortEmail15.58 ns0.055 ns0.052 ns0.480.000.0089-56 B1.00
ValidIa5BenchmarksWriteMainMainShortEmail34.38 ns0.046 ns0.043 ns1.000.000.0153-96 B1.00
ValidIa5BenchmarksWriteVectorVectorShortEmail18.39 ns0.120 ns0.100 ns0.530.000.0153-96 B1.00
ValidIa5BenchmarksDecodeMainMainLongEmail85.55 ns0.106 ns0.099 ns1.000.000.0216-136 B1.00
ValidIa5BenchmarksDecodeVectorVectorLongEmail29.65 ns0.068 ns0.064 ns0.350.000.0216-136 B1.00
ValidIa5BenchmarksWriteMainMainLongEmail85.93 ns0.120 ns0.112 ns1.000.000.0216-136 B1.00
ValidIa5BenchmarksWriteVectorVectorLongEmail32.17 ns0.109 ns0.102 ns0.370.000.0216-136 B1.00
ValidIa5BenchmarksDecodeMainMainUri92.23 ns0.885 ns0.784 ns1.000.010.0242-152 B1.00
ValidIa5BenchmarksDecodeVectorVectorUri33.22 ns0.060 ns0.056 ns0.360.000.0242-152 B1.00
ValidIa5BenchmarksWriteMainMainUri94.65 ns0.060 ns0.050 ns1.000.000.0216-136 B1.00
ValidIa5BenchmarksWriteVectorVectorUri35.81 ns0.071 ns0.067 ns0.380.000.0216-136 B1.00
ValidIa5BenchmarksDecodeMainMainLength820.08 ns0.025 ns0.024 ns1.000.000.0063-40 B1.00
ValidIa5BenchmarksDecodeVectorVectorLength817.22 ns0.029 ns0.027 ns0.860.000.0063-40 B1.00
ValidIa5BenchmarksWriteMainMainLength823.01 ns0.048 ns0.044 ns1.000.000.0140-88 B1.00
ValidIa5BenchmarksWriteVectorVectorLength819.68 ns0.038 ns0.036 ns0.860.000.0140-88 B1.00
ValidIa5BenchmarksDecodeMainMainLength1630.80 ns0.047 ns0.044 ns1.000.000.0089-56 B1.00
ValidIa5BenchmarksDecodeVectorVectorLength1615.08 ns0.135 ns0.126 ns0.490.000.0089-56 B1.00
ValidIa5BenchmarksWriteMainMainLength1632.43 ns0.054 ns0.050 ns1.000.000.0153-96 B1.00
ValidIa5BenchmarksWriteVectorVectorLength1617.36 ns0.045 ns0.042 ns0.540.000.0153-96 B1.00
ValidIa5BenchmarksDecodeMainMainLength3251.66 ns0.082 ns0.077 ns1.000.000.0140-88 B1.00
ValidIa5BenchmarksDecodeVectorVectorLength3217.70 ns0.068 ns0.061 ns0.340.000.0140-88 B1.00
ValidIa5BenchmarksWriteMainMainLength3252.76 ns0.074 ns0.069 ns1.000.000.0178-112 B1.00
ValidIa5BenchmarksWriteVectorVectorLength3221.06 ns0.079 ns0.062 ns0.400.000.0179-112 B1.00
ValidIa5BenchmarksDecodeMainMainLength6496.62 ns0.143 ns0.134 ns1.000.000.0242-152 B1.00
ValidIa5BenchmarksDecodeVectorVectorLength6424.60 ns0.115 ns0.096 ns0.250.000.0242-152 B1.00
ValidIa5BenchmarksWriteMainMainLength64106.81 ns0.158 ns0.140 ns1.000.000.0229-144 B1.00
ValidIa5BenchmarksWriteVectorVectorLength6428.05 ns0.050 ns0.047 ns0.260.000.0229-144 B1.00
ValidIa5BenchmarksDecodeMainMainLength128195.11 ns0.174 ns0.155 ns1.000.000.0446-280 B1.00
ValidIa5BenchmarksDecodeVectorVectorLength12838.80 ns0.120 ns0.112 ns0.200.000.0446-280 B1.00
ValidIa5BenchmarksWriteMainMainLength128196.89 ns0.083 ns0.073 ns1.000.000.0331-208 B1.00
ValidIa5BenchmarksWriteVectorVectorLength12843.85 ns0.104 ns0.087 ns0.220.000.0331-208 B1.00
ValidIa5BenchmarksDecodeMainMainLength256367.03 ns0.271 ns0.240 ns1.000.000.0854-536 B1.00
ValidIa5BenchmarksDecodeVectorVectorLength25664.32 ns0.209 ns0.195 ns0.180.000.0854-536 B1.00
ValidIa5BenchmarksWriteMainMainLength256359.23 ns0.373 ns0.348 ns1.000.000.0534-336 B1.00
ValidIa5BenchmarksWriteVectorVectorLength25673.64 ns0.117 ns0.104 ns0.200.000.0535-336 B1.00
ValidIa5BenchmarksDecodeMainMainLength10241,389.09 ns12.097 ns10.724 ns1.000.010.3300-2072 B1.00
ValidIa5BenchmarksDecodeVectorVectorLength1024222.03 ns0.713 ns0.557 ns0.160.000.3302-2072 B1.00
ValidIa5BenchmarksWriteMainMainLength10241,350.11 ns1.211 ns1.073 ns1.000.000.1755-1104 B1.00
ValidIa5BenchmarksWriteVectorVectorLength1024253.19 ns0.493 ns0.461 ns0.190.000.1760-1104 B1.00
ValidIa5BenchmarksDecodeMainMainLength40965,436.07 ns6.509 ns6.088 ns1.000.001.3046-8216 B1.00
ValidIa5BenchmarksDecodeVectorVectorLength4096863.95 ns1.696 ns1.324 ns0.160.001.3084-8216 B1.00
ValidIa5BenchmarksWriteMainMainLength40965,328.17 ns5.326 ns4.982 ns1.000.000.66380.00764176 B1.00
ValidIa5BenchmarksWriteVectorVectorLength40961,000.79 ns1.553 ns1.453 ns0.190.000.66570.00954176 B1.00
InvalidIa5BenchmarksDecodeInvalidMainMainLongEmailLate2,933.39 ns13.165 ns11.671 ns1.000.010.1984-1264 B1.00
InvalidIa5BenchmarksDecodeInvalidVectorVectorLongEmailLate2,918.78 ns5.534 ns4.321 ns1.000.000.1984-1264 B1.00
InvalidIa5BenchmarksWriteInvalidMainMainLongEmailLate1,232.75 ns8.312 ns7.369 ns1.000.010.1221-776 B1.00
InvalidIa5BenchmarksWriteInvalidVectorVectorLongEmailLate1,194.64 ns5.756 ns5.103 ns0.970.010.1221-776 B1.00
VisibleStringBenchmarksDecodeMainMainShortText24.09 ns0.029 ns0.026 ns1.000.000.0076-48 B1.00
VisibleStringBenchmarksDecodeVectorVectorShortText19.82 ns0.027 ns0.025 ns0.820.000.0076-48 B1.00
VisibleStringBenchmarksWriteMainMainShortText26.24 ns0.038 ns0.033 ns1.000.000.0140-88 B1.00
VisibleStringBenchmarksWriteVectorVectorShortText21.92 ns0.047 ns0.042 ns0.840.000.0140-88 B1.00
VisibleStringBenchmarksDecodeMainMainUri95.28 ns0.210 ns0.197 ns1.000.000.0242-152 B1.00
VisibleStringBenchmarksDecodeVectorVectorUri33.43 ns0.084 ns0.079 ns0.350.000.0242-152 B1.00
VisibleStringBenchmarksWriteMainMainUri94.32 ns0.072 ns0.068 ns1.000.000.0216-136 B1.00
VisibleStringBenchmarksWriteVectorVectorUri35.50 ns0.070 ns0.065 ns0.380.000.0216-136 B1.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
MemberAuthor

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

@vcsjones

Copy link
Copy Markdown
MemberAuthor

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.

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

CopilotAI 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
FileDescription
src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.net.csAdds vectorized range-based encoding/decoding implementation for IA5/VisibleString on .NET.
src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.downlevel.csKeeps downlevel behavior by mapping RestrictedAsciiRangeEncoding to the existing restricted ASCII encoder.
src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.csUpdates IA5/VisibleString encodings to use the new range-based base type.
src/libraries/System.Formats.Asn1/src/System.Formats.Asn1.csprojAdds conditional compile includes for the new files and references System.Numerics.Vectors for .NET builds.
src/libraries/System.Formats.Asn1/tests/Writer/WriteIA5String.csAdds an invalid IA5 input with an invalid character after a vector-sized prefix.
src/libraries/System.Formats.Asn1/tests/Writer/SimpleWriterTests.csAdds VisibleString writer tests for vector-sized payloads and invalid character index reporting.
src/libraries/System.Formats.Asn1/tests/Reader/ReadIA5String.csAdds IA5 reader coverage for a longer valid input and a vector-prefix invalid input case.
src/libraries/System.Formats.Asn1/tests/Reader/ComprehensiveReadTests.csAdds 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
MemberAuthor

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

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

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

Copy link
Copy Markdown
MemberAuthor

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

CopilotAI 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:mainJul 21, 2026
83 checks passed
@vcsjones
vcsjones deleted the vector-asn1-string branch July 21, 2026 19:17
@vcsjonesvcsjones mentioned this pull request Jul 21, 2026
vcsjones added a commit that referenced this pull request Jul 29, 2026
As a follow up to #131109, this introduces vectorization for the `BMPEncoding`.
BMPEncoding is big-endian UCS-2 encoding. It is a subset of UTF-16-BE, with the exception that it is truly fixed width and only supports plane 0 without the surrogate pairs.
This also makes some changes to the existing vectorization logic for JIT friendliness.
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 23, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@vcsjones@tannergooding@bartonjs