【问题标题】:C# Lookup ptimisation suggestion are welcome欢迎 C# 查找优化建议
【发布时间】:2012-09-14 13:02:03
【问题描述】:

我有下面的代码可以满足我的需要,但我知道它可以更快。请让我知道是否可以通过任何方式改进此代码...

主要问题是我需要多次查询“数据”。我只需要确保没有我可以使用的快捷方式。

data= GetData()// this return ILookup<Tuple(string, string, string),string>
foreach (var v0 in data)
{
    if (v0.Key.Item3 == string.Empty)
    {
        //Get all related data
        var tr_line = data[v0.Key];
        sb.AppendLine(tr_line.First());

        foreach (var v1 in data)
        {
            if (v1.Key.Item2 == string.Empty && v1.Key.Item1 == v0.Key.Item1)
            {
                var hh_line = data[v1.Key];
                sb.AppendLine(hh_line.First());

                foreach (var v2 in data)
                {
                    if (v2.Key.Item1 == v0.Key.Item1 && v2.Key.Item2 != string.Empty && v2.Key.Item3 != string.Empty)
                    {
                        var hl_sl_lines = data[v2.Key].OrderByDescending(r => r);
                        foreach (var v3 in hl_sl_lines)
                        {
                            sb.AppendLine(v3);
                        }
                    }
                }
            }
        }
    }
 } 

【问题讨论】:

  • GetData 返回什么类型? IGrouping 的数组还是字典?
  • 请描述你需要代码做什么;只是在那里倾倒一堵代码并问“它可以更好吗?”不可能得到你想要的。
  • 您确定GetData() 的返回类型吗?因为我的环境不喜欢v0.Key
  • 现在执行需要多少时间?
  • 好吧,我没有这样的性能问题......这只是为了知道我是否没有使用任何可以用来检索相关分层数据的好功能。

标签: c# linq ilookup


【解决方案1】:

更整洁,更多 linq:

        var data = GetData();

        foreach (var v0 in data)
        {
            if (v0.Key.Item3 != string.Empty) continue;

            //Get all related data 
            var tr_line = data[v0.Key];
            sb.AppendLine(tr_line.First());

            var hhLines = from v1 in data
                          where v1.Key.Item2 == string.Empty &&
                                v1.Key.Item1 == v0.Key.Item1
                          select data[v1.Key];

            foreach (var hh_line in hhLines)
            {
                sb.AppendLine(hh_line.First());

                var grouping = v0;
                var enumerable = from v2 in data
                                 where v2.Key.Item1 == grouping.Key.Item1 &&
                                       v2.Key.Item2 != string.Empty &&
                                       v2.Key.Item3 != string.Empty
                                 select data[v2.Key].OrderByDescending(r => r)
                                 into hl_sl_lines from v3 in hl_sl_lines select v3;

                foreach (var v3 in enumerable)
                {
                    sb.AppendLine(v3);
                }
            }
        }

【讨论】:

  • 嗯,这看起来确实更整洁,但结果却是我的原始代码的两倍。
  • 请丢弃好吧,这看起来确实更整洁,更Linq。更多测试显示速度没有重大差异。非常感谢您对 linq 和 c# 的深刻见解。
【解决方案2】:

首先,尽量避免在这种代码中使用元组,因为即使对你来说,几个月后,这段代码也会变得难以理解。使用正确的属性名称创建一个类,甚至更好的不可变结构。如果无法维护,即使是最快的代码也毫无价值。

也就是说,您有三个迭代同一个集合的嵌套循环。排序后的集合执行得更快似乎是合理的,因为您只需要与相邻的项目进行比较。

请尝试解释您要完成的工作,以便有人会尝试提供更具体的帮助。

【讨论】:

  • 我有一个复杂的 CSV 文件。我使用 linq 来检索文件的行并查询这些行。然后将结果存储在查找对象 (GetData()) 中。该文件包含多个不同类型的记录。一些记录以 HH 开头,其他以 HL 开头,依此类推……但是为了符合格式,它们(行)需要以特定顺序出现。所需的层次结构最好用我上面写的代码来描述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多