所以基本上添加和处理字符串的方法通常会被其他方式所取代,因为它会导致混乱和浪费资源。 我同意,但我想知道究竟是什么导致了资源的浪费......正如这里所说的那样。
'..你正在运行一个没有的实现 处理字符串的复杂代码,你最终可以做很多事情 浪费了分配...' Link 字符串缓冲方法如何避免这种浪费...
答案 0 :(得分:3)
我对此的解释来自Java / .NET背景,但是同样的逻辑适用。
<强> 1。你必须学习可变和不可变对象的概念......
像Int32 / Integer这样的对象是可变对象,这意味着它们可以在实例化后在其当前内存位置进行更改。这是因为无论对象的值如何,它在内存中的大小都不需要改变。
字符串是不可变对象,这意味着一旦分配它们,就无法在当前内存位置进行更改。这是因为字符串本质上可以是任意长度,因此,每次字符串更改长度时,系统/运行时必须在内存中找到一个新位置来存储字符串。
<强> 2。连接与StringBuilder / StringBuffer
由于字符串是不可变的,因此每个连接都会强制重新分配内存。让我们假设以下示例使用ASCII编码(每个字符1个字节)
var message = "Hello World";
此时,系统已分配11个字节的内存来存储您的字符串。
message += "Hello Universe";
此时,系统必须为原始字符串分配另外14个字节。您现有的11个字节的内存无法再存储新字符串!
为什么“用于处理字符串的复杂代码”(StringBuffer
/ StringBuilder
)可以帮助您!
每次向缓冲区/构建器追加一个字符串时,它都会分配一次内存,并在内存中保存一个指向该字符串的指针。下次分配字符串时,它会在新位置执行,而不会影响最后一个字符串。一旦你完成了字符串的构建,缓冲区/构建器就会将所有内容连接成一个字符串,因此你的字符串分配会大大减少,因为每次向缓冲区/构建器添加内容时都不会这样做!
示例:
StringBuilder builder = new StringBuilder();
builder.Append("Hello World");
此时构建器已分配了11个字节,并按原样保留该分配!
builder.Append("Hello Universe");
此时,构建器分配了另外14个字节,留下最后一个字符串。
builder.ToString();
此时,构建器将内存中的所有字符串连接成一个字符串!
<强>要点:强>
连接是浪费资源,因为:
系统/运行时必须清除旧的,取消引用的内存位置,这需要一些CPU时间。在Java / .NET中,它被称为垃圾收集。
每次重新分配内存都是浪费,直到垃圾收集器可以去清理它!
因此,连接会降低CPU和内存使用的性能!