0

我有一个包含 2 列的 csv 文件,ID并且Flag. 有很多Flag值,但有一些表示坏事——错误、失败等。我需要做的很简单——搜索Flag列以查看这些值中是否有任何值在“坏标志”组中。

我有以下代码可以满足我的需要-检查标志文件是否存在,遍历每一行,将其拆分,然后检查当前行是否具有标志元素,然后检查标志是否在我的错误组中-如果我什至发现一个我已经完成了:

private bool CheckFlagStatus( string directory )
{
    // Bad flags
    const int Flag1 = 1;
    const int Flag2 = 5; 
    const int Flag3 = 6;
    const int Flag4 = 42;
    const int Flag5 = 61;

    bool isGood = true;
    string flagFilePath= Path.Combine( directory, "flags.csv" );
    if ( File.Exists( flagFilePath) )
    {
        using ( StreamReader reader = new StreamReader( flagFilePath) )
        {
            string line;
            while ( !string.IsNullOrEmpty( line = reader.ReadLine() ) )
            {
                var splitval = line.Split(',');
                if ( splitval.Length == 2 )
                {
                    var flagString = splitval[1];
                    int flag;
                    bool parsed = Int32.TryParse( flagString, out flag );
                    if ( parsed )
                    {
                        if ( flag == Flag1 || flag == Flag2 || flag == Flag3
                            || flag == Flag4 || flag == Flag5 )
                        {
                            isGood = false;
                            break;
                        }
                    }
                }
            }
        }
    }
    return isGood;
}

虽然这可行,但这是一种非常线性的蛮力方法。虽然完美的带有 20 行的 flags.csv 文件,但如果有一百万行会发生什么?我想知道关于如何使它更优雅或优化它的一些建议。

4

2 回答 2

1

这已经优化了。如果有一百万行会花费更长的时间,但性能是线性的,这比大多数算法要好得多。您可以使您的代码更优雅,但这只是样式问题,与您实际在做什么或它的优化程度无关。请记住,优化的代码通常更冗长。

通过执行类似于File.ReadLines然后拆分新行然后拆分,然后循环列表仅查看奇数索引的操作,您的代码可能会更优雅(行更少),但性能不会更好。事实上,情况可能会更糟。

于 2013-04-09T15:52:58.793 回答
1

您的代码没问题,检查每一行都必须是这样,我只是尝试通过使用 LINQ 和Readlines方法使您的代码更具可读性:

private bool CheckFlagStatus(string directory)
{
    badFlags = new[] { 1, 5, 6, 42, 61};
    string flagFilePath = Path.Combine(directory, "flags.csv" );

    if (File.Exists(flagFilePath))
    {
        var lines = File.ReadLines(flagFilePath)
                        .Where(line => !string.IsNullOrEmpty(line));

        foreach (var line in lines)
        {
            var splitval = line.Split(',');
            if (splitval.Length == 2)
            {
                var flagString = splitval.Last();
                int flag;

                if (int.TryParse(flagString, out flag))
                {
                    if (badFlags.Contains(flag)) return false;
                }
            }
        }    
    }
    return true;
}
于 2013-04-09T15:58:22.170 回答