Cache delegates
See original GitHub issueConsider this code:
open System.Collections.Concurrent
let d = ConcurrentDictionary<string, int>()
let getOrAdd key = d.GetOrAdd(key, fun _ -> 0)
for _ = 0 to 1_000_000 do
getOrAdd "" |> ignore
When memory profiling (using dotMemory, targeting .NET 7), I see that this allocates 1 million Func<String, Int32>
objects:
Allocated type : System.Func<String, Int32>
Objects : 1000001
Bytes : 64000064
Allocated by
100% getOrAdd • 61,04 MB / 61,04 MB • global::Program.getOrAdd(String)
100% main@ • 61,04 MB / - • <StartupCode$AllocTest>.$Program.main@()
► 100% [AllThreadsRoot] • 61,04 MB / - • [AllThreadsRoot]
This is very surprising to me. (Although I’m no expert in esoteric subjects like compiler optimizations, I consider myself a fairly experienced F# developer.)
I propose that F# caches these delegates. (Note: I am unsure if “delegates” is the right term.)
Possibly related: #910, https://github.com/dotnet/runtime/issues/80430
Issue Analytics
- State:
- Created 8 months ago
- Reactions:1
- Comments:7 (5 by maintainers)
Top Results From Across the Web
Lambda Expressions, Method Groups, and delegate caching
Delegates are used to pass methods as arguments to other methods. The most common delegates are Action , Func<T> , and EventHandler ....
Read more >Why aren't delegate instances always cached?
It can't cache it for instance methods because the target instance is part of the delegate, and it really wants to use a...
Read more >C# Delegates and Memory Allocations: Summary - Matt Gibson
Caching the delegate requires added logic and an additional memory reference. If in the majority of cases delegates only end up being used...
Read more >Use a cached delegate for method group conversion #5835
The method group conversion today always creates a fresh delegate instance. ... Cache delegates created from static methods #19452.
Read more >9.3.2. Cache loaders that delegate to other caches
Cache loaders that delegate to other caches. LocalDelegatingCacheLoader , which enables loading from and storing to another local (same JVM) cache.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
https://github.com/fsharp/fslang-suggestions/issues/1083
Essentially
Foo(x => Bar(x))
was cached, butFoo(Bar)
wasn’t