文章目录
C# 中的
string
和
StringBuilder
类主要在内存管理和字符串操作性能上存在显著区别:
StringBuilder和String 对比
String 类:
- 不可变性:字符串是不可变的,每次对字符串进行修改(如拼接、替换等)时,都会创建一个新的字符串实例。
- 内存分配:由于不可变性,每次字符串操作都需要在内存堆中为新字符串分配空间,这会导致频繁的内存分配和垃圾回收。
- 性能:对于单个或少量的字符串操作,性能影响可能不大。但在大量或频繁的字符串连接操作(尤其是循环中),会产生大量的中间字符串,严重影响性能。
StringBuilder 类:
- 可变性:StringBuilder 是可变的,可以在原对象上直接修改内容,不会生成新的对象。
- 内存效率:它预先分配了一定大小的缓冲区,并且可以根据需要动态扩展容量,减少了内存分配次数,从而提高了内存使用效率。
- 性能:适用于处理多个字符串拼接的情况,尤其是在循环或其他需要多次修改字符串的场景下,其性能远优于 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经典脚本(41-50)
————————————————
最后我们放松一下眼睛