实习字符串会有助于解析器的性能吗?
如果你正在解析,就说HTML,一旦你读取了元素名称,对实习它会有好处吗?这里的逻辑是这个解析器会一遍又一遍地解析相同的字符串(元素名称)?并且将解析多个文档。
理论:
// elemName is checked for null.
MarkupNode node = new MarkupNode()
{
Name = String.IsInterned(elemName) ? elemName : String.Intern(elemName),
...
};
这个问题是由问题 string-interning-memory 引发的。
If you are parsing, lets just say HTML, once you read the element name, will it be beneficial to intern it? The logic here is that this parser will parse the same strings (element names) over and over again? And several documents will be parsed.
Theory:
// elemName is checked for null.
MarkupNode node = new MarkupNode()
{
Name = String.IsInterned(elemName) ? elemName : String.Intern(elemName),
...
};
This question was motivated by the question string-interning-memory.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我真的无法确切地说这是否会对你的表现有所帮助。这取决于您使用的字符串数量以及创建这些字符串实例的频率。驻留通常是自动完成的,因此显式检查字符串是否被驻留实际上可能会增加开销并降低性能。当谈到内存使用时,内部字符串肯定可以使用更少的内存。
如果您确实希望使用字符串驻留,有一些更好的方法可以实现它。首先也是最重要的,我会将元素名称粘贴在一个充满公共字符串常量的静态类中。在程序源代码中找到的任何字符串文字都肯定会自动保留。当您的应用程序加载时,此类字符串将被加载到实习池中。如果您的字符串无法定义为编译时实习生准备的常量,那么我只需调用 String.Intern(...) 而不是执行完整的三元表达式 String.IsInterned( ...)? ...:String.Intern(...)。 Intern 方法将自动检查字符串是否被实习,如果是则返回实习版本,否则将字符串添加到实习池中,如果不是则返回。无需自己手动检查 IsInterned。
同样,我不能说手动驻留字符串是否会提高性能。如果您使用常量,它们将以最优化的方式自动为您保留,这是提高定期重用字符串的性能和内存使用率的最佳方法。老实说,我建议您远离手动实习,并让编译器和运行时为您处理优化。
I couldn't really say exactly whether this would help your performance or not. It would depend on how many strings you use, and how frequently you create instances of those strings. Interning is generally done automatically, so explicitly checking if the string is interned may actually increase your overhead and reduce your performance. When it comes to memory usage, interned strings can definitely use less memory.
If you do wish to use string interning, there are some better ways to achieve it. First and foremost, I would stick your element names in a static class full of public string constants. Any string literal found in your program source code is definitely and automatically interned. Such strings are loaded into the intern pool when your application is loaded. If your strings can not be defined as constants for compile-time intern preparation, then I would simply call String.Intern(...) rather than doing the full ternary expression String.IsInterned(...) ? ... : String.Intern(...). The Intern method will automatically check if the string is interned, return the interned version if it is, and will otherwise add the string to the intern pool and return that if it is not. No need to manually check IsInterned yourself.
Again, I can not say whether manually interning strings will improve performance. If you use constants, they will be automatically interned for you, in the most optimal way, and that is the best approach to improving performance and memory usage of regularly reused strings. I would honestly recommend you stay away from manual interning, and let the compiler and runtime handle optimization for you.
当然,实习字符串有助于提高性能,但正如 @jrista 所说“如果您使用常量,它们将自动为您实习,...”。
这里有一些文章可能对您有帮助,
优化 C# 字符串性能
摘要:共享内存,C# 维护着一个称为“实习生表”的东西。这是当前引用的字符串列表。如果创建了新字符串,则检查实习表。如果您的字符串已经在那里,那么两个变量将指向由实习生表维护的同一内存块。
http://blog.cumps.be/string-concatenation-vs-memory -分配/
Of course, interning strings help performanance but as @jrista said "If you use constants, they will be automatically interned for you,...".
Here are some articles might help you,
Optimizing C# String Performance
SUMMARY: Sharing Memory, C# maintains something called an "intern table." This is a list of strings that are currently referenced. If a new string is created, then the intern table is checked. If your string is already in there, then both variables will point at the same block of memory maintained by the intern table.
http://blog.cumps.be/string-concatenation-vs-memory-allocation/