解析此字符串的最快方法是什么

时间:2009-10-14 16:00:34

标签: c# parsing .net-2.0 performance

我有一个字符串,格式如下:

[季节] [年] [供应商] [地理]

所以一个例子可能是: 2009年春季尼尔森MSA

我需要能够以最快的方式解析季节和年份。我不关心漂亮或聪明。只是原始速度。该语言是使用VS2008的C#,但该程序集是为.NET 2.0构建的

7 个答案:

答案 0 :(得分:11)

如果你只需要季节和年份,那么:

int firstSpace = text.IndexOf(' ');
string season = text.Substring(0, firstSpace);
int secondSpace = text.IndexOf(' ', firstSpace + 1);
int year = int.Parse(text.Substring(firstSpace + 1, 
                                    secondSpace - firstSpace - 1));

如果你可以假设年份总是四位数,那就更快了:

int firstSpace = text.IndexOf(' ');
string season = text.Substring(0, firstSpace);
int year = int.Parse(text.Substring(firstSpace + 1, 4));

如果另外你知道所有年份都在21世纪,它可能会变得愚蠢地最佳:

int firstSpace = text.IndexOf(' ');
string season = text.Substring(0, firstSpace);
int year = 2000 + 10 * (text[firstSpace + 3] - '0') 
                + text[firstSpace + 4] - '0';

变得更不易读,但可能更快(取决于JIT的作用):

int firstSpace = text.IndexOf(' ');
string season = text.Substring(0, firstSpace);
int year = 1472 + 10 * text[firstSpace + 3] + text[firstSpace + 4];

就我个人而言,我认为至少有一步太过分了:)

编辑:好的,把它带到极端......你只会有几个季节,对吧?假设他们是“春天”,“夏天”,“秋天”,“冬天”,那么你可以这样做:

string season;
int yearStart;
if (text[0] == 'S')
{
    season = text[1] == 'p' ? "Spring" : "Summer";
    yearStart = 7;
}
else if (text[0] == 'F')
{
    season = "Fall";
    yearStart = 5;
}
else
{
    season = "Winter";
    yearStart = 7;
}

int year = 1472 + 10 * text[yearStart + 2] + text[yearStart + 3];

这样做的好处是它将重用相同的字符串对象。当然,它假设数据中没有任何错误...

使用Spidey的答案中显示的Split肯定比任何一个都简单,但我怀疑它会稍微慢些。说实话,我至少尝试首先......你测量过最简单的代码并发现它太慢了吗?差异可能非常小 - 当然,与您首先在数据中读取的任何网络或磁盘访问相比。

答案 1 :(得分:5)

要添加其他答案,如果您希望它们采用以下格式:

Spring xxxx
Summer xxxx
Autumn xxxx
Winter xxxx

然后更快的方式是:

string season = text.Substring(0, 6);
int year = int.Parse(text.Substring(7, 4);

相当令人讨厌。 :)

我不会甚至考虑这样编码。

答案 2 :(得分:4)

试试这个。

        string str = "Spring 2009 Nielsen MSA";
        string[] words = str.Split(' ');
        str = words[0] + " " + words[1];

答案 3 :(得分:1)

string input = "Spring 2009 Nielsen MSA";

int seasonIndex = input.IndexOf(' ') + 1;

string season = input.SubString(0, seasonIndex - 2);
string year = input.SubString(seasonIndex, input.IndexOf(' ', seasonIndex) - seasonIndex);

答案 4 :(得分:1)

string[] split = stringName.Split(' ');
split[0]+" "+split[1];

答案 5 :(得分:0)

Class Parser:

public class Parser : StringReader {

    public Parser(string s) : base(s) {
    }

    public string NextWord() {
        while ((Peek() >= 0) && (char.IsWhiteSpace((char) Peek())))
            Read();
        StringBuilder sb = new StringBuilder();
        do {
            int next = Read();
            if (next < 0)
                break;
            char nextChar = (char) next;
            if (char.IsWhiteSpace(nextChar))
                break;
            sb.Append(nextChar);
        } while (true);
        return sb.ToString();
    }
}

使用:

    string str = "Spring 2009 Nielsen MSA";
    Parser parser = new Parser(str);
    string season = parser.NextWord();
    string year = parser.NextWord();
    string vendor = parser.NextWord();
    string geography = parser.NextWord();

答案 6 :(得分:0)

我得到了Spidey的建议,这应该是足够好的性能,但是具有简单,易于理解,易于维护的代码。

但如果你真的需要推动性能。信封(和C#是唯一可用的工具)然后可能是一系列搜索空格的循环,然后使用substr拉出字符串会略微超过它。

您可以使用IndexOf而不是循环执行相同操作,但滚动您自己的可能稍快一点(但您必须对其进行分析)。