本文目录 14 个章节
C# string及其性能问题
创建时间:2020/9/28 17:13
string介绍
char
Represents a character as a UTF-16 code unit. 值类型 , 在C#中以结构体的形式定义
Object -> ValueType -> Char
public struct Char : IComparable, IComparable<char>, IConvertible, IEquatable<char>
string & System.String
Object -> String
In C#, the string keyword is an alias for String. String and string are equivalent, and you can use whichever naming convention you prefer.
关于值类型与引用类型
String类型直接继承自Object,这使得它成为一个引用类型,也就是说线程上的堆栈上不会驻留有任何字 符串。字符串都存储在heap当中。
- 值类型 都继承自System.ValueType 直接继承自Object的类型一定是 引用类型 。因此System.ValueType是一个引用类型。
C#中避免字符串冗余的机制
The CLR conserves string storage by maintaining a table(是一个散列表), called the intern pool(驻留池), that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently, an instance of a literal string with a particular value only exists once in the system.
string str1 = "test";
string str2 = "test";
当构造str1时,先会去散列表(驻留池)中查询是否存在”test”字符串,如果不存在那么会在托管堆中构造一个新的String对象,然后将”test”字符串和指向该对象的引用添加到散列表(驻留池)中,当构造str2时,由于散列表中存在 Key为”test”的键值对,于是将Value值(”test”的引用)赋值给str2。
string a = "test";
string tmp = "est";
string b = "t" + tmp;
Console.WriteLine(string .ReferenceEquals(str1, str2));
以上代码,虽然a和b最终的字符串相同,但在编译时,编译器并无法判断要给b的字符串就是”test”,只有执行完给b的赋值语句之后,才知道b引用的字符串,而此时创建新字符串的过程已经结束。因此,a和b指向的是不同的String对象。 输出为 false。
String.Intern(String) Method
string str1 = String.Empty;
string str2 = String.Empty;
str2 = String.Intern(sb.ToString());
if((object)str1==(object)str2)
Console.WriteLine("The strings are equal.");
else
Console.WriteLine("The strings are not equal.");
Intern方法使用驻留池搜索等于值的字符串 str 。 如果存在这样的字符串,则返回暂存池中的引用。 如果该字符串不存在,则会将对的引用 str 添加到拘留池中,然后返回该引用。
In the .NET Framework 2.0 Service Pack 1 and .NET Framework 3.0, str1 and str2 are not equal. In all other versions, str1 and str2 are equal.
那么string.Empty和 “” 哪个性能好?
使用空的字符串”“在初始化时,会检查内部池,这会花费一些宝贵的CPU时间。使用string.Empty,则将传递对象引用,这意味着不会分配额外的内存,也不会浪费额外的CPU周期检查内部缓冲池。
Empty Strings and Null Strings
An empty string is an instance of a System.String object that contains zero characters.
string s = String.Empty;
By contrast, a null string does not refer to an instance of a System.String object and any attempt to call a method on a null string causes a NullReferenceException.
Immutability 不可变性
they cannot be changed after they have been created. The += operator creates a new string that contains the combined contents. That new object is assigned to the variable s1, and the original object that was assigned to s1 is released for garbage collection because no other variable holds a reference to it. a string “modification” is actually a new string creation 因此,修改string会造成额外的堆内存分配,消耗内存,增加GC压力。
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
经常改变string的值则应该使用StringBuilder而不使用string
Using StringBuilder for Fast String Creation
The StringBuilder class creates a string buffer that offers better performance if your program performs many string manipulations. StringBuilder使用char类型的数组存储字符串,改变某个字符的值不会创建新的string。
默认容量为16个字符,Append时不总是需要分配内存(有点类似于C++ vector的机制)。 Additional memory for the StringBuilder object is allocated dynamically until it reaches the value defined by the StringBuilder.MaxCapacity property. If the number of added characters causes the length of the StringBuilder object to exceed its current capacity, new memory is allocated, the value of the Capacity property is doubled.
使用String
When the number of changes that your app will make to a string is small. In these cases, StringBuilder might offer negligible or no performance improvement over String.
When you are performing a fixed number of concatenation operations, particularly with string literals. In this case, the compiler might combine the concatenation operations into a single operation.
When you have to perform extensive search operations while you are building your string. The StringBuilder class lacks search methods such as IndexOf or StartsWith. You’ll have to convert the StringBuilder object to a String for these operations, and this can negate the performance benefit from using StringBuilder. For more information, see the Searching the text in a StringBuilder object section.
使用StringBuilder
When you expect your app to make an unknown number of changes to a string at design time (for example, when you are using a loop to concatenate a random number of strings that contain user input).
When you expect your app to make a significant number of changes to a string.
延伸——Built-in reference types
object
string
delegate
dynamic - 运行时才解析的类型
class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;
dyn = dyn + 3;
//obj = obj + 3; 报错
// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
输出: System.Int32 System.Int32
Ref
https://docs.microsoft.com/zh-cn/dotnet/api/system.string.intern?view=netcore-3.1 https://blog.csdn.net/u010019717/article/details/106034974