通过字符数组的C#循环无效
本文关键字:循环 无效 数组 字符 | 更新日期: 2023-09-27 18:22:16
下面有这段代码,我在其中循环字符串并逐字符比较所有内容,这是一个非常缓慢的过程,我想知道如何改进这段代码。
//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;
这太神奇了。
我已经更改了2行,并获得了惊人的性能提升,如1000%或
首先更改此
string ch = googlejson.Substring(x, 1);
到
string ch = googlejson[x].ToString();
第二,我用字符串生成器替换了所有+=ch
output.Append(ch);
因此,这两项更改对性能的影响最大。
首先,当只处理单个字符时,不应该使用Substring
s。使用
char ch = googlejson[x];
相反。
您也可以考虑为output
变量使用StringBuilder
。如果您使用字符串,您应该始终记住,字符串在.NET中是不可变的,因此对于每个
output += ch;
创建了一个新的字符串实例。
使用
StringBuilder output = new StringBuilder();
和
output.append(ch);
相反。
根据其他评论,这段代码使用字符串作为字符和Substring()在性能方面非常糟糕。此外,使用Regex检查空白将是非常低效的。
如果要对字符进行操作,请使用字符(char)而不是字符串。
for循环的效率有点低,但JIT编译器可能会对此进行优化。与其访问Length属性,不如使用局部变量。
当切换字符的速度非常快时,切换字符串的效率也非常低。
正如MartinStettner所建议的,StringBuilder附加将更好地构建结果。(@Tom Squires-这个问题都是关于性能的,所以是的,它确实很重要,而且并不更复杂——可能还有几个角色,但这并不复杂。
最后,我想说的是,如果你有性能问题(除了这个可怕的代码),你应该考虑在进行优化之前用探查器来衡量它。
PS这看起来像是一个面试问题。。。啧啧——如果是这样的话,那不是SO的意思。
为什么不使用StringReader
而不是SubString
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))