question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Consider 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:closed
  • Created 8 months ago
  • Reactions:1
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

0reactions
jl0pdcommented, Jan 12, 2023

I’m not clear on the details/differences

Essentially Foo(x => Bar(x)) was cached, but Foo(Bar) wasn’t

Read more comments on GitHub >

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

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found