将所有 String 元素从 List 连接到 String 的最快方法

Posted

技术标签:

【中文标题】将所有 String 元素从 List 连接到 String 的最快方法【英文标题】:Quickest way to concatenate all String elements from List to String 【发布时间】:2016-09-26 23:08:09 【问题描述】:

我的网站上有大量用户对象,每个对象都包含他们管理的论坛列表。我创建了一个页面,该页面将显示管理论坛的所有用户的分页列表以及所有论坛名称。

例如

特拉维斯 - FTB、SCR、SWM、BSB

汤姆 - FTB、SCR、SWM、BSB、TRK、BSK

但是,有些用户可能管理 300 多个不同的主题,导致页面处理时间非常长。

我尝试了以下方法来加快处理速度,但所有这些方法都花费了大约相同的时间(太长)。

//Join
topicString = String.Join(", ", user.Topics)
(note that Topics.ToString returns a 3 character ID)

//StringBuilder
StringBuilder stringBuilder = new StringBuilder(3*user.Topics.Count() + 2*user.Topics.Count());
foreach(var topic in user.Topics) 
   stringBuilder.Append(topic.Code);
   stringBuilder.Append(", ");

codes = stringBuilder.ToString();
codes = codes.Remove(codes.Length-2);


//Classic concatenation
foreach(var topic in user.Topics) 
    codes += topic.Code;
    codes += ", ";

codes = codes.Remove(codes.Length-2);

每个页面包含 15 个用户

当所有 15 个用户都包含大约 3 个主题时,加载页面大约需要 1 秒。任何有 1 个用户包含超过 100 个主题的页面,页面加载时间都会飙升至接近 20 秒。

有没有办法通过线程来加快速度?

【问题讨论】:

您确定问题出在连接上吗?对于 100 个 3 个字符的字符串的连接,20 秒似乎有点太多了 我同意史蒂夫的观点——你说的是“页面加载”,而不是“字符串连接时间”。这可能不是瓶颈。瓶颈可能是由于随后在数据库上运行的查询比您需要的多 100 个(或类似的事情)。 我建议你在怀疑瓶颈之前使用var sw = new System.Diagnostics.Stopwatch(); sw.Start();,在之后使用sw.Stop(); var time = sw.Elapsed.TotalSeconds;。我的猜测是字符串连接甚至不会注册 1 秒。 秒表读数为 18 秒。那么可能是因为延迟加载数据库? 您需要显示用于生成响应的方法的完整代码。问题显然与字符串连接无关。 【参考方案1】:

正如在 cmets 中提到的那样,从数据库中获取数据而不是字符串连接导致的性能问题。延迟加载在这里令人困惑。

字符串生成器将在字符串长度超过 100 万个字符时显示其威力。当您使用 String.Join() 方法时,它将在内部使用字符串生成器。

对代码的一点性能改进是在将其转换为字符串之前设置字符串构建器长度以避免两次创建大字符串对象:

// StringBuilder
StringBuilder stringBuilder = new StringBuilder();
foreach (var topic in user.Topics) 
   stringBuilder.Append(topic.Code);
   stringBuilder.Append(", ");

stringBuilder.length--;
codes = stringBuilder.ToString();

不必指定字符串生成器大小,因为它的大小调整算法足够快。

我使用大小超过 1 亿个字符的字符串生成器类,在这种情况下,它比普通字符串连接快大约 10,000 倍。

【讨论】:

以上是关于将所有 String 元素从 List 连接到 String 的最快方法的主要内容,如果未能解决你的问题,请参考以下文章

将数组中的元素连接到字符串

C# 从 List<T> 中选择存在于另一个列表中的所有元素

Linq 多个连接到 SelectList

mongodb / mongoose mapreduce - 将所有值连接到单个数组

C# 使用 LINQ 将 List<string> 的所有元素替换为相同的模式

从 iOS 应用程序中列出(并连接到)蓝牙设备