字符串连接和复杂性?当我需要连接两个字符串时,我使用String.Format(或StringBuilder,如果它出现在代码中的多个位置)。我看到一些优秀的程序员不注意字符串连接的复杂性而只使用“+”运算符。我知道使用“+”运算符会使应用程序使用更多内存,但复杂性如何呢?这是一篇来自我们自己的JeffAtwood编码恐怖片的关于不同字符串连接方法的优秀帖子:替代文本http://sofzh.miximages.com/c%23/微优化剧院的悲剧这是帖子的要点。[显示的几种字符串连接方法]把你发痒的小扳机手指从编译键上拿开,想想这个。哪种方法会更快?你有答案吗?大的!还有..请打鼓...正确答案:它。仅有的。不,东西!此答案假设您在谈论运行时复杂性。使用+创建一个新的字符串对象,这意味着必须将旧字符串对象的内容复制到新字符串对象中。对于大量连接,例如在紧密循环中,这可能变成O(n^2)操作。作为非正式证明,假设您有以下代码:stringfoo="a";for(inti=0;i循环的第一次迭代,首先将foo("a")的内容复制到一个新的字符串对象中,然后是文字"a"的内容。这是两份。第二次迭代有三个副本;两个来自newfoo,一个来自文字“a”。第1000次迭代将有1001个副本操作。副本总数为2+3+...+1001。一般来说,如果在一个循环中,每次迭代只拼接一个字符(且以一个字符长开始),如果迭代次数为n,则有2+3+...+n+1份。这与1+2+3+相同...+n=n(n+1)/2=(n^2+n)/2,即O(n^2)。视情况而定。+有时可以降低代码复杂度。考虑以下代码:output=""+intro+"";这是一条很好的清晰路线。不需要String.Format。如果你只使用+一次,你没有缺点,它增加了可读性(正如ColinPicard已经说过的)。据我所知+意味着:获取左右操作数并将它们复制到新缓冲区(因为字符串是不可变的)。所以使用+两次(如在ColinPickards示例中,您创建了2个临时字符串。首先将“”添加到介绍中,然后将“”添加到新创建的字符串中。您必须自己考虑何时使用哪种方式。即使对于上面的小例子,如果intro是一个足够大的字符串,性能会受到严重影响。除非你的应用程序是字符串密集型的(配置文件,配置文件,配置文件!),否则没关系。优秀的程序员优先考虑可读性超越琐碎操作的性能。我认为就复杂性而言,您需要换出重新创建的新字符串来解析格式字符串......例如,“A”+“B”+“C”+“D”意味着你有复制“A”、“AB”,最后是“ABC”,形成“ABCD”。复制就是重复,对吧?因此,例如,如果您有一个包含1000个字符的字符串,您将添加一千个字符串,您将复制(1000+N)字符串1000次。在最坏的情况下,它会导致O(n^2)。Strin.Fomat,StringBuffer应该在O(n)左右,即使考虑解析。因为字符串在Java和C#等语言中是不可变的,所以每次连接两个字符串时,都必须在复制两个旧字符串内容的地方创建一个新字符串。假设一串平均长度为c个字符。现在第一个连接只需要复制2*c个字符,但最后一个连接必须复制第一个n-1个字符串的连接,即(n-1)*c个字符长,以及最后一个字符本身,即c个字符长,总共n*c个字符。对于n个连接,这会生成n^2*c/2个字符副本,这意味着算法复杂度为O(n^2)。在实践中的大多数情况下,这种二次复杂性并不明显(正如JeffAtwood在RobertC.Cartaino条目链接的博客中那样),我建议编写尽可能可读的代码。然而,在某些情况下它确实很重要,在这种情况下使用O(n^2)可能是致命的。在实践中,我已经看到了这个,例如在内存中生成大型WordXML文件,包括base64编码的图片。由于O(n^2)字符串连接,这一代过去需要10多分钟。使用+与StringBuilder替换连接后,同一文档的运行时间减少到10秒以下。同样,我见过一个软件使用+进行连接,生成一个非常大的SQL代码作为字符串。我什至没有等到它完成(已经等了一个多小时),而是用StringBuilder重写了它。这个更快的版本在一分钟内完成。简而言之,只做最易读/最容易编写的事情,只有在创建一个巨大的字符串时才考虑这一点:-)如果您分几步构建一个大字符串,您应该使用StringBuilder。如果您知道它最终有多大也是一件好事,那么您可以使用您需要的大小初始化它并防止重新分配成本。对于小型操作,使用+运算符不会导致相当大的性能损失,并且会产生更清晰的代码(编写速度更快...)打了很多字,但我一直觉得这是解决性能问题的最佳方法是了解所有可能方案的性能差异,对于满足性能要求的方案,选择最可靠可靠的方案。支持的。有很多人使用大O表示法来理解复杂性,但我发现在大多数情况下(包括理解哪种字符串连接方法最有效),简单的时间试验就足够了。只需在100,000次迭代的循环中将strA+strB与strA.Append(strB)进行比较,看看哪个工作得更快。编译器将字符串文字连接优化为一个字符串文字。例如:字符串s="a"+"b"+"c";在编译时优化为以下内容:strings="abc";有关详细信息,请参阅此问题和此MSDN文章。编译器将优化:“a”+“b”+“c”将被String.Concat方法替换(不是String.Format一个修复我的评论)我在.NET1.0或1.1之前和之后对此进行了基准测试因为它没有真的很重要。那时,如果您有几个进程最多能够连接字符串数百万次的代码序列,那么使用String.Concat、String.Format或StringBuilder可能会大大加快速度。现在一点都不重要了。至少已经不重要了。Net2.0还是出来了。让它远离你的头脑和代码,让你以最简单的方式阅读。以上就是C#学习教程:字符串连接和复杂度?如果分享的所有内容对您有用,需要了解更多C#学习教程,希望您多多关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
