简体   繁体   English

来自 Guid 的有效 string.Intern

[英]effective string.Intern from Guid

Rider dynamic program analysis shows me that following line of code is repeatedly allocating in total about 338MB. Rider 动态程序分析显示,以下代码行重复分配总共约 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这只是强类型 ID 的片段,值一遍又一遍地重复,所以我猜只有很少的唯一值,这就是为什么 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.荒谬的是,我需要先将 Guid 转换为字符串(它分配该内存)以发现该字符串已被实习并立即使用该实习生。 Which seems to me like wasting of allocations.在我看来,这就像浪费分配。

Is there a way to get string.Intern from Guid/span of chars?有没有办法从字符的 Guid/span 获取 string.Intern?

Is there a way to get string.Intern from Guid/span of chars?有没有办法从字符的 Guid/span 获取 string.Intern?

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.您可以遍历实习池中的所有string值,将它们解析为Guid值,并将任何成功解析的值与您想要字符串的Guid值进行比较。 .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? .NET 不提供从实习池中检索string值的直接方法,但您可以查看例如是否可以读取实习池中的所有字符串? 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.我希望你能看到,即使你不必为了从实习池中获取string值的集合而跳过流程自省循环,也可以通过实习池进行线性搜索以找到与你对应的那个Guid值不会提高性能。

On the other hand, you could just cache the string values yourself with a Dictionary<Guid, string> :另一方面,您可以使用Dictionary<Guid, string>自己缓存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.但是,如果您需要更精细的缓存方案,.NET 现在包含您可以使用的MemoryCache class。

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; .NET 针对小对象的频繁分配进行了优化; 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).据推测,一旦有任何显着的 memory 压力(在现代机器上可能永远不会,这取决于程序正在做什么,但同样,这不应该成为问题),就会收集 338MB。

I suspect you could just call ToString() on the Guid value every single time you need the string value, and it would be fine.我怀疑您每次需要string值时都可以在Guid值上调用ToString() ,这样就可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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