Skip to content

Conversation

@pavelsavara
Copy link
Member

@pavelsavara pavelsavara commented Jan 18, 2026

For single-threaded Browser runtime

  • in EncodingTable and TimeZoneInfo
  • don't use ConcurrentDictionary and other items from System.Collections.Concurrent assembly in the CoreLib
    • so that we do not keep those types from trimming. Download size matters.
    • so that we don't have to spend CPU cycles on synchronization. We are mostly interpreting the IL.
    • previously we already did this for ConcurrentQueue in ThreadPoolWorkQueue
  • this covers it with System.Runtime.Tests/TrimmingTests/DoesntIncludeConcurentTypes.cs
    • testing that we are trimming those types and whole assembly System.Collections.Concurrent
  • make explicit dependency of System.ComponentModel.TypeDescriptor on ConcurrentDictionary in ILLink.Descriptors.LibraryBuild.xml
    • TypeDescriptor is already heavily marked with RequiresUnreferencedCodeAttribute

@pavelsavara pavelsavara added this to the 11.0.0 milestone Jan 18, 2026
@pavelsavara pavelsavara self-assigned this Jan 18, 2026
@pavelsavara pavelsavara added arch-wasm WebAssembly architecture area-System.Globalization size-reduction Issues impacting final app size primary for size sensitive workloads os-browser Browser variant of arch-wasm labels Jan 18, 2026
@dotnet-policy-service dotnet-policy-service bot added the linkable-framework Issues associated with delivering a linker friendly framework label Jan 18, 2026
@dotnet-policy-service
Copy link
Contributor

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

@pavelsavara pavelsavara requested a review from maraf January 19, 2026 19:38
@jkotas
Copy link
Member

jkotas commented Jan 19, 2026

Do you have any numbers for how much this saves for user apps?

ConcurrentDictionary is used pretty frequently for performance reasons. It is not practical to ifdef out every use of it. If we are not happy about its footprint for single threaded wasm, it may be better to provide an alternative lighter weight implementation instead of trying to ifdef out every use.

cc @stephentoub

@pavelsavara
Copy link
Member Author

I admit that most normal applications would use those data structures.
On the other hand, some customers are very interested in pay for play size and I had to #ifdef only 2 places in corelib.

On the left is the same app with extra

        var x=new System.Collections.Concurrent.ConcurrentDictionary<int, int>();
        x[1] = 1;
        Console.WriteLine(x[1]);
        var y=new System.Collections.Concurrent.ConcurrentBag<int>();
        y.Add(1);
image

The difference is 46kb uncompressed.
Regarding perf I hope that R2R of just normal Dictionary would serve us better than to have 2 code bases.

Anyway, even if we revert most of this, I would like to keep non concurrent Queue in ThreadPoolWorkQueue and cover it with similar trimming test I drafted here.

@jkotas
Copy link
Member

jkotas commented Jan 19, 2026

On the left is the same app with extra

I would like to see number for a Blazor app. (total size / bytes saved by this change)

I had to #ifdef only 2 places in corelib.

Ifdefs like this tend to keep growing to the point of being non-sustainable.

non concurrent Queue in ThreadPoolWorkQueue

That's fine with me. Queue is used a lot less frequently and ThreadPool has a bunch of ifdefs for single-threaded wasm, so one more does not sound like a problem.

@stephentoub
Copy link
Member

I agree if there's a need for something like this, we should instead just have alternate impls of those data structures for the single threaded wasm use. Could be as simple as the public API shimming to a wrapped dictionary/queue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-System.Globalization linkable-framework Issues associated with delivering a linker friendly framework os-browser Browser variant of arch-wasm size-reduction Issues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants