C# StringBuilder对比string的优点和15大案例

发布时间:2024年01月03日


C# 中的 stringStringBuilder 类主要在内存管理和字符串操作性能上存在显著区别:

StringBuilder和String 对比

String 类:

  1. 不可变性:字符串是不可变的,每次对字符串进行修改(如拼接、替换等)时,都会创建一个新的字符串实例。
  2. 内存分配:由于不可变性,每次字符串操作都需要在内存堆中为新字符串分配空间,这会导致频繁的内存分配和垃圾回收。
  3. 性能:对于单个或少量的字符串操作,性能影响可能不大。但在大量或频繁的字符串连接操作(尤其是循环中),会产生大量的中间字符串,严重影响性能。

StringBuilder 类:

  1. 可变性:StringBuilder 是可变的,可以在原对象上直接修改内容,不会生成新的对象。
  2. 内存效率:它预先分配了一定大小的缓冲区,并且可以根据需要动态扩展容量,减少了内存分配次数,从而提高了内存使用效率。
  3. 性能:适用于处理多个字符串拼接的情况,尤其是在循环或其他需要多次修改字符串的场景下,其性能远优于 String 类。

提升性能的使用案例

以下是十个展示 StringBuilder 在性能优化方面应用的示例:

1. 循环内字符串连接

string result = "";
for (int i = 0; i < 10000; i++)
{
    // 错误的做法,会生成很多临时字符串
    // result += "Item" + i;

    // 正确的做法,使用 StringBuilder
    StringBuilder sb = new StringBuilder();
    sb.Append("Item");
    sb.Append(i);
    result = sb.ToString(); // 只在循环结束后生成最终字符串
}

2. 构建大型日志消息

StringBuilder logBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
    logBuilder.Append(data[i].ToString());
    logBuilder.Append(",");
}
string logMessage = logBuilder.ToString().TrimEnd(',');

3. 格式化长字符串

StringBuilder reportBuilder = new StringBuilder();
foreach (var item in reportData)
{
    reportBuilder.AppendFormat("ID: {0}, Name: {1}, Value: {2}\n", item.Id, item.Name, item.Value);
}
string report = reportBuilder.ToString();

4. SQL 查询构造

StringBuilder sqlQuery = new StringBuilder("SELECT * FROM Users WHERE ");
bool isFirst = true;
foreach (var condition in conditions)
{
    if (!isFirst)
        sqlQuery.Append(" AND ");
    sqlQuery.Append($"Column = '{condition}'");
    isFirst = false;
}
ExecuteSql(sqlQuery.ToString());

5. 从文件读取并合并行

StringBuilder fileContent = new StringBuilder();
using (StreamReader reader = new StreamReader("largeFile.txt"))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        fileContent.AppendLine(line);
    }
}
string completeFileText = fileContent.ToString();

6. 拼接数组元素

int[] numbers = Enumerable.Range(1, 10000).ToArray();
StringBuilder numStr = new StringBuilder();
foreach (int number in numbers)
{
    numStr.Append(number.ToString());
    numStr.Append(",");
}
string numList = numStr.ToString().TrimEnd(',');

7. 格式化电子邮件模板

StringBuilder emailBody = new StringBuilder(emailTemplate);
emailBody.Replace("{Name}", customer.Name);
emailBody.Replace("{OrderNo}", order.OrderNumber);
SendEmail(customer.Email, emailBody.ToString());

8. 处理用户输入流

StringBuilder inputBuffer = new StringBuilder();
while (streamReader.Peek() >= 0)
{
    inputBuffer.Append((char)streamReader.Read());
}
ProcessInput(inputBuffer.ToString());

9. JSON 或 XML 格式的序列化与构建

StringBuilder jsonBuilder = new StringBuilder("[");
for (int i = 0; i < list.Count; i++)
{
    jsonBuilder.Append(JsonConvert.SerializeObject(list[i]));
    if (i < list.Count - 1)
        jsonBuilder.Append(",");
}
jsonBuilder.Append("]");
string jsonArray = jsonBuilder.ToString();

10. 动态生成 HTML 页面

```csharp
StringBuilder htmlPage = new StringBuilder("<html><body>");
foreach (var article in articles)
{
    htmlPage.AppendFormat("<h2>{0}</h2><p>{1}</p>", article.Title, article.Content);
}
htmlPage.Append("</body></html>");
return htmlPage.ToString();
```

11. 构建长路径名

StringBuilder pathBuilder = new StringBuilder();
pathBuilder.Append(basePath);
foreach (string directory in directories)
{
    pathBuilder.Append(Path.DirectorySeparatorChar);
    pathBuilder.Append(directory);
}
string fullPath = pathBuilder.ToString();

12. 处理大量字符串分割与合并

```csharp
string[] parts = longString.Split(';');
StringBuilder rebuiltString = new StringBuilder();
for (int i = 0; i < parts.Length; i++)
{
    rebuiltString.Append(parts[i].Trim());
    if (i < parts.Length - 1)
        rebuiltString.Append("; ");
}
string processedString = rebuiltString.ToString();
```

13. 格式化复杂的表格数据

```csharp
StringBuilder tableBuilder = new StringBuilder();
foreach (var row in dataTable.Rows)
{
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        tableBuilder.Append(row[i].ToString().PadRight(20));
        if (i < dataTable.Columns.Count - 1)
            tableBuilder.Append("|");
    }
    tableBuilder.AppendLine();
}
string formattedTable = tableBuilder.ToString();
```

14. 动态生成SQL IN子句

```csharp
List<int> ids = GetIds();
StringBuilder inClause = new StringBuilder("IN (");
for (int i = 0; i < ids.Count; i++)
{
    inClause.Append(ids[i]);
    if (i < ids.Count - 1)
        inClause.Append(",");
}
inClause.Append(")");
ExecuteSql($"SELECT * FROM Users WHERE Id {inClause.ToString()}"); 
```

15. 拼接加密后的密码散列

```csharp
StringBuilder passwordHashBuilder = new StringBuilder();
using (SHA256 sha256 = SHA256.Create())
{
    byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
    foreach (byte b in hashBytes)
    {
        passwordHashBuilder.Append(b.ToString("x2"));
    }
}
string passwordHash = passwordHashBuilder.ToString();
```

以上这些例子再次强调了在需要频繁修改和拼接字符串的场景下,StringBuilder相比于string能够显著提升性能。

python学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

?最后我们放松一下眼睛
在这里插入图片描述

文章来源:https://blog.csdn.net/qqrrjj2011/article/details/135370510
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。