简体   繁体   中英

effective string.Intern from Guid

Rider dynamic program analysis shows me that following line of code is repeatedly allocating in total about 338MB.

Guid subscriptionId = .....
var s = string.Intern(subscriptionId.ToString());

This is just snippet from strongly typed IDs, the values repeat over and over, so I guess that there only few unique values, that's why string.Intern

The ridiculous is that I need to convert Guid to string first (which allocates that memory) to find out that this string is already interned and immediately use that intern one. Which seems to me like wasting of allocations.

Is there a way to get string.Intern from Guid/span of chars?

Is there a way to get string.Intern from Guid/span of chars?

In theory, yes. You could iterate through all the string values in the intern pool, parse them as Guid values, and compare any successfully parsed values to the Guid value you want the string for. .NET doesn't offer a direct way to retrieve the string values from the intern pool, but you can look at eg Is it possible to read all strings in the intern pool? for info about how you might still accomplish that (it involves, essentially, debugging your own program from within at runtime).

I hope you see how, even if you didn't have to jump through the process-introspection hoops just to get the collection of string values from the intern pool, that a linear search through the intern pool to find the one that corresponds to your Guid value isn't going to be a performance improvement.

On the other hand, you could just cache the string values yourself with a Dictionary<Guid, string> :

Dictionary<Guid, string> guidCache = new Dictionary<Guid, string>();

Guid subscriptionId = .....
if (!guidCache.TryGetValue(subscriptionId, out string s))
{
    s = subscriptionId.ToString();
    guidCache[subscriptionId] = s;
}

For something simple like this, the above should suffice. But if you need a more elaborate caching scheme, .NET now includes the MemoryCache class you could use instead.

All that said, I'm skeptical that there's really any need for any of this. .NET is optimized to deal with frequent allocations of small objects; it shouldn't be an actual problem. Presumably, that 338MB gets collected once there's any significant memory pressure (which on a modern machine might be never, depending on what else the program is doing but, again, that shouldn't be a problem).

I suspect you could just call ToString() on the Guid value every single time you need the string value, and it would be fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM