C#循环通过字符数组无效

C#循环通过字符数组无效,c#,C#,我在下面有一段代码,我循环遍历字符串并逐字符比较所有内容,这是一个非常缓慢的过程,我想知道如何改进这段代码 //delete anti-xss junk ")]}'\n" (5 chars); if (trim) { googlejson = googlejson.Substring(5); } //pass through result and turn empty elements in

我在下面有一段代码,我循环遍历字符串并逐字符比较所有内容,这是一个非常缓慢的过程,我想知道如何改进这段代码

        //delete anti-xss junk ")]}'\n" (5 chars);
        if (trim)
        {
            googlejson = googlejson.Substring(5);
        }

        //pass through result and turn empty elements into nulls
        //echo strlen( $googlejson ) . '<br>';
        bool instring = false;
        bool inescape = false;
        string lastchar = "";
        string output = "";
        for ( int x=0; x< googlejson.Length; x++ ) {

            string ch = googlejson.Substring(x, 1);

            //toss unnecessary whitespace
            if ( !instring && ( Regex.IsMatch(ch, @"/\s/"))) {
                continue;
            }

            //handle strings
            if ( instring ) {
                if (inescape) {
                    output += ch;
                    inescape = false;
                } else if ( ch == "\\" ) {
                    output += ch;
                    inescape = true;
                } else if ( ch == "\"") {
                    output += ch;
                    instring = false;
                } else {
                    output += ch;
                }
                lastchar = ch;
                continue;
            }


            switch ( ch ) {

                case "\"":
                    output += ch;
                    instring = true;
                    break;

                case ",":
                    if ( lastchar == "," || lastchar == "[" || lastchar == "{" ) { 
                        output += "null";
                    }
                    output += ch;
                    break;
                case "]":
                case "}":
                    if ( lastchar == "," ) { 
                        output += "null";
                    }
                    output += ch;
                    break;

                default:
                    output += ch;
                    break;
            }
            lastchar = ch;
        }
        return output;
到那

string ch = googlejson[x].ToString();
第二,我用字符串生成器替换了all+=ch

output.Append(ch);

因此,这两个更改对性能的影响最大。

首先,当只处理单个字符时,不应使用
子字符串。使用

char ch = googlejson[x];
相反

您也可以考虑使用<代码> StringBuilder <代码>为您的代码>输出< /代码>变量。如果您使用字符串,您应该始终记住,字符串在.NET中是不可变的,所以对于每个

output += ch;
创建了一个新的字符串实例

使用


相反。

根据其他注释,这段代码使用字符串作为字符和子字符串()在性能方面非常糟糕。 此外,使用正则表达式检查空白将是非常低效的

如果要对字符进行操作,请使用字符(char)而不是字符串

for循环有点低效,但JIT编译器可能会对此进行优化。使用局部变量而不是访问Length属性会稍微好一些

当打开字符的速度非常快时,打开字符串也是非常低效的

正如MartinStettner所建议的,StringBuilder append将更好地构建结果。(@Tom Squires-这个问题都是关于性能的,所以是的,它确实很重要,而且它并不复杂-可能会多几个角色,但这并不复杂

最后,我会说,如果你有性能问题(除了这个可怕的代码),你应该考虑在进行优化之前先用一个分析器测量它。 PS这看起来像一个面试问题……啧啧啧啧如果是这样,那就不是问题所在。

为什么不使用代替
子字符串

var output = new StringBuilder();

using (var reader = new StringReader(googleJson)
{
    var buffer = new char[1]
    while (reader.Read(buffer, 0, 1) == 1)
    {
        var ch = buffer[0];

        //your stuff

        output.Append(ch);
    }
}

return output.ToString();
您可以使用
StringReader.Read()
并对字符的整数代码值执行所有逻辑操作,这可能会很快,但有点脆弱。

关于:
if(!instring&&(Regex.IsMatch(ch,@/\s/)))


if(!instring&ch<33)

或者更好:

if(!instring&&Char.IsWhiteSpace(ch))

在任何现代系统上,StringBuilder的性能增益都是如此之小,以至于复杂性的增加毫无意义@Tom Squires,它真的有那么复杂吗?@Jodrell它不太复杂,但性能增益可以忽略不计,即使是少量的额外复杂性也不值得。@TomSquires that link解决了这样的问题不在循环中。当它不是循环时,c#将
+
替换为
String.Concat
。在循环中
StringBuilder
使用是必要的,不要相信你读到的所有内容-profile!这不完全正确。对于小示例(如你提到的帖子中的示例)当然,差别很小。对于只有10个附录,二次复杂度并不重要(同样,如果在新字符串上运行相同的10个附录数千次…)但在这里介绍的循环中,它确实很重要。我做了一个简单的测试,添加一个字符10000次。StringBuilder的时间为7ms,
+=
串联的时间为3238ms!!所以我认为,如果你在循环中添加字符,你应该始终使用StringBuilder(如果你需要多次迭代)不要这样做<代码> GoGoLyjs.Sub(x,1)因为代码只有一个<代码> for循环< /代码>,我认为它很慢,不是因为代码不高效,而是因为代码复杂。没有考虑改进您的方法(因为我不知道您的要求),如果您担心UI的无响应时间过长,我建议您将该函数放在backgroundworker中,如果您还没有实现progressbar,则可以实现它。我认为您会发现StringReader.Read()调用的开销超过了简单的googleJson[I]。StringReader()的分配/初始化也没有必要,对于小循环可能是可测量的。
StringBuilder output = new StringBuilder();
output.append(ch);
var output = new StringBuilder();

using (var reader = new StringReader(googleJson)
{
    var buffer = new char[1]
    while (reader.Read(buffer, 0, 1) == 1)
    {
        var ch = buffer[0];

        //your stuff

        output.Append(ch);
    }
}

return output.ToString();