将string.Split替换为其他构造 - 优化

时间:2011-12-14 04:53:09

标签: c# string optimization compiler-optimization string-search

这里我使用Split函数来获取字符串的部分。

string[] OrSets = SubLogic.Split('|');
foreach (string OrSet in OrSets)
{
  bool OrSetFinalResult = false;
    if (OrSet.Contains('&'))
    {
        OrSetFinalResult = true;
        if (OrSet.Contains('0'))
        {
            OrSetFinalResult = false;
        }
        //string[] AndSets = OrSet.Split('&');
        //foreach (string AndSet in AndSets)
        //{
        //    if (AndSet == "0")
        //    {
        //        // A single "false" statement makes the entire And statement FALSE
        //        OrSetFinalResult = false;
        //        break;
        //    }
        //}

    }
    else
    {
        if (OrSet == "1")
        {
            OrSetFinalResult = true;
        }
    }

    if (OrSetFinalResult)
    {
        // A single "true" statement makes the entire OR statement TRUE
        FinalResult = true;
        break;
    }
}

如何替换Split操作以及替换foreach构造。

3 个答案:

答案 0 :(得分:1)

如果您需要优化以提高应用程序的性能,那么foreach循环中的代码 是需要优化的,而不是string.Split方法。

[编辑:]

StackOverflow上的其他地方有很多与优化字符串解析相关的好答案:

String.Split()可能比你自己做的更多,实际上以一种经过优化的方式分割字符串。当然,这假设您对输入的每个拆分部分返回true或false很有意思。否则,您可以专注于搜索字符串。

正如其他人所提到的,如果你需要搜索一个巨大的字符串(数百兆字节),特别是反复连续地搜索,那么看看.NET 4给你的Task Parallel Library

要搜索字符串,可以查看MSDN上的this example,了解如何使用IndexOf,LastIndexOf,StartsWith和EndsWith方法。那些应该比Contains方法表现更好。

当然,最好的解决方案取决于您特定情况的事实。您需要使用System.Diagnostics.Stopwatch class来查看您的实施(包括当前和新的)需要多长时间才能看到最佳效果。

答案 1 :(得分:1)

假设#1

根据您的流程类型,您可以平行工作:

var OrSets = SubLogic.Split('|').AsParallel();
foreach (string OrSet in OrSets)
{
  ...
  ....
}

但是,这通常会导致多线程应用程序出现问题(锁定资源等)。 而且你还要测量它的好处。从一个线程切换到另一个线程可能是昂贵的。如果作业很小,AsParallel将比简单的顺序循环慢。

当您遇到网络资源延迟或任何类型的I / O时,这非常有效。

假设#2

您的SubLogic变量非常非常大

在这种情况下,您可以顺序遍历文件:

class Program
{
    static void Main(string[] args)
    {
        var SubLogic = "darere|gfgfgg|gfgfg";

        using (var sr = new StringReader(SubLogic))
        {

            var str = string.Empty;
            int charValue;
            do
            {
                charValue = sr.Read();
                var c = (char)charValue;
                if (c == '|' || (charValue == -1 && str.Length > 0))
                {
                    Process(str);
                    str = string.Empty; // Reset the string
                }
                else
                {
                    str += c;
                }
            } while (charValue >= 0);

        }

        Console.ReadLine();
    }

    private static void Process(string str)
    {
        // Your actual Job
        Console.WriteLine(str);
    }

此外,根据|之间每个块的长度,您可能希望使用StringBuilder而不是简单的字符串连接。

答案 2 :(得分:0)

您可以使用StringBuilder来处理它。 尝试将源字符串中的char-by-char读入StringBuilder,直到找到“|”,然后处理StringBuilder包含的内容。 这就是为什么你要避免创造吨String个对象并节省大量内存。

如果您使用过Java,我建议使用StringTokenizerStreamTokenizer类。遗憾的是.NET中没有类似的类