c#基础系列2---深入理解 String
2021-07-12 06:06
标签:很多 har https acm sedm str1 build jpeg logs “大菜”:源于自己刚踏入猿途混沌时起,自我感觉不是一般的菜,因而得名“大菜”,于自身共勉。 string(严格来说应该是System.String) 类型是我们日常coding中用的最多的类型之一。那什么是String呢?^ ~ ^ String是一个不可变的连续16位的Unicode代码值的集合,它直接派生自System.Object类型。 与之对应的还有一个不常用的安全字符串类型System.Security.SecureString,它会在非托管的内存上分配,以便避开GC的黑手。主要用于安全性特高的场景。[具体可查看msdn这里不展开讨论了。=>msdn查看详情 常量字符串的拼接和非常量字符串在CLR中行为是不一样的。具体请查看性能部分。 String.Intern String.IsInterned 具体请查看msdn(https://msdn.microsoft.com/zh-cn/library/system.string.isinterned(v=vs.110).aspx) 输出结果: 可见实例的值只分配了一次,但是有一点需要说明,字符串仅用于编译期能确定值的字符串,也就是常量字符串。如果我的程序修改为: 运行结果: 运行结果: 查看GC的情况 Gc执行的是如此频繁。 性能是可想而知的。接着看一下StringBuilder 运行结果: GC情况: 几乎没有GC(可能还未达到触发GC的临界点),如果我合理初始化了StringBuilder 容量,生产环境中结果差距将会更大。 呵呵 ^ ~ ^ 这个场景是适合字符串留用的。因为不再需要经过以上的两个步骤,直接哈希表拿到value就可以对比确定了。 基于以上所有知识,那是不是StringBuilder拼接字符串性能永远都高于符号‘+’呢?答案是否定的。 运行结果: 符号‘+’最终会调用String.Concat方法,当同时连接几个字符串时,并不是每连接一个都分配一次内存,而是把几个字符都作为 String.Concat方法的参数,只分配一次内存。所以在拼接的字符串个数比较少的场景下,String.Concat 性能是略高于StringBuilder.Append。string.Format 方法最终调用的是StringBuilder,这里不做展开讨论了,请自行参考其他文档。 所以万事都不是绝对的!!每个事物都有适合自己的场景,我们都需要自己去探索。( 以上都是非生产环境测试结果,如果错误,请及时指正 请尊重一个猿的辛苦,转载请标明出处 ^ ~ ^ 。部分图片来源于网络,如有侵权请及时联系。让我们一起进步吧 一个不止于IT圈内容的微信公众号,欢迎关注,交流更多的IT知识。不定时会有惊喜奥 ^ ~ ^ c#基础系列2---深入理解 String 标签:很多 har https acm sedm str1 build jpeg logs 原文地址:https://www.cnblogs.com/zhanlang/p/9612521.html
扩展阅读:深入理解值类型和引用类型基本概念
特性
注意事项
static void Main(string[] args)
{
string a = "c:\\temp\\1";
string b = @"c:\temp\1";
Console.WriteLine(a);
Console.WriteLine(b);
Console.Read();
}
性能
String类型提供了两个静态方法来操作这个哈希表:
但是c#编译器默认是不开启字符串留用功能的,因为如果程序大量把字符串留用,应用程序总体性能可能会变得更慢。(微软也是挺纠结的,程序员TMD的更纠结)
string s1 = "hello 大菜";
string s2 = "hello 大菜";
unsafe
{
ixed (char* p = s1)
{
Console.WriteLine("字符串地址= 0x{0:x}", (int)p);
}
fixed (char* p = s2)
{
Console.WriteLine("字符串地址= 0x{0:x}", (int)p);
}
}
字符串地址= 0x80002d84
字符串地址= 0x80002d84
args = new string[] { "dfasfdsa"};
string s1 = "hello 大菜"+ args[0];
string s2 = "hello 大菜"+args[0];
unsafe
{
fixed (char* p = s1)
{
Console.WriteLine("字符串地址= 0x{0:x}", (int)p);
}
fixed (char* p = s2)
{
Console.WriteLine("字符串地址= 0x{0:x}", (int)p);
}
}
字符串地址= 0x2e3c
字符串地址= 0x2e7c
int count = 100000;
Stopwatch sw = new Stopwatch();
sw.Start();
string s = "";
for (int i = 0; i
14221
int count = 100000;
Stopwatch sw = new Stopwatch();
sw.Start();
StringBuilder sb = new StringBuilder();//听说程序员都这样命名StringBuilder
for (int i = 0; i
12
其他
关于字符串留用和字符串池
关于字符串拼接性能
static void Main(string[] args)
{
int count = 10000000;
Stopwatch sw = new Stopwatch();
sw.Start();
string str1 = "str1", str2 = "str2", str3 = "str3";
for (int i = 0; i
+用时: 553
StringBuilder.Append 用时: 975
程序员太累了)