【问题标题】:Improve performance of code提高代码性能
【发布时间】:2014-09-11 10:48:56
【问题描述】:

要求:我有两个字符串数组。 empDetails 数组包含四个字段,假设字段一是 ID,其他字段是详细信息。 empToRemove 数组包含要删除的员工 ID。创建不包含 empToRomove 数组中存在的 ID 的数组字符串。请注意,我必须使用这段代码,它在 empDetails 中包含超过 100000 个数据,在 empToRemove 中包含超过 20000 个数据。 任何建议都非常合适。

string[] empDetails = { "1,abc,2,11k", "2,de,3,11k", "3,abc,2,18k", "4,abdc,2,12k" };

string[] empToRemove = { "1","3" };

我的解决方案

class Program
  {
    static void Main(string[] args)
    {
        string[] empDetails = { "1,abc,2,11k", "2,de,3,11k", "3,abc,2,18k", "4,abdc,2,12k" };

        string[] empToRemove = { "1","3" };

        //Add emp details in list of employee
        List<emp> e = new List<emp>();
        foreach (var item in empDetails)
        {
            Dictionary<int, string> tempEmployee = new Dictionary<int, string>();
            int i = 1;
            foreach (string details in item.Split(','))
            {
                tempEmployee.Add(i, details);
                i++;
            }
            e.Add(new emp { ID = int.Parse(tempEmployee[1]), Details1 = tempEmployee[2], Details2 = tempEmployee[3], Details3 = tempEmployee[4] });
        }
        foreach (string item in empToRemove)
        {
            emp employeeToRemove = e.Where(x => x.ID == int.Parse(item)).Single();
            e.Remove(employeeToRemove);
        }
        foreach (var item in e)
        {
            Console.WriteLine(item.ID + item.Details1 + item.Details2 + item.Details3);
        }
        Console.ReadLine();
    }
}
class emp
{
    public int ID { get; set; }
    public string Details1 { get; set; }
    public string Details2 { get; set; }
    public string Details3 { get; set; }
}

谢谢

【问题讨论】:

  • 如果可行,您需要在code review 上发布。
  • 每个人都听说过数据库吗?它们旨在做到这一点。
  • 或者这个empDetails = empDetails.ToList().Select(val =&gt; val.Split(new char[] { ',' })).ToList().Where(val =&gt; !empToRemove.Contains(val[0])).ToList().Select(val =&gt; string.Join(",", val)).ToArray();

标签: c# arrays linq generics


【解决方案1】:

如果我正确理解了您的要求并且您唯一需要的就是打印(或以其他方式操作)id 不在 empToRemove 中的 empDetails 元素,那么您的代码就完全过分了。 以下就足够了:

string[] empDetails = { "1,abc,2,11k", "2,de,3,11k", "3,abc,2,18k", "4,abdc,2,12k" };
string[] empToRemove = { "1", "3" };

var remove = new HashSet<string>(empToRemove);
foreach (var item in empDetails)
{
    string id = item.Substring(0, item.IndexOf(','));
    if (!remove.Contains(id))
        Console.WriteLine(item); // or your custom action with this item
}

【讨论】:

    【解决方案2】:
        string[] empDetails = { "1,abc,2,11k", "2,de,3,11k", "3,abc,2,18k", "4,abdc,2,12k" };
        string[] empToRemove = { "1","3" };
    
        foreach (string item in empToRemove)        
          empDetails = empDetails.Where(val => val.Substring(0, val.IndexOf(',')) != item).ToArray(); 
    

    是一种方式。没有比这更有效的了吗?

    基于以下研究:

    How to delete an element from an array in C#

    【讨论】:

    • 现在可以了。忘记获取子字符串
    • @ravenx30 仍然没有。 ID 大于 9 怎么办?
    • @ravenx30 如果我们谈论的是性能 - 你的代码至少比我建议的慢 N 倍,其中 N 是 empToRemove 数组的大小。那是因为您的代码在 empDetails 上执行 linq where 方法 N 次,每次调用将花费 O(M) 时间,其中 M 是 empDetails 的大小。 LINQ 是一个非常好的东西,但不是“灵丹妙药”,应该合理使用。
    • 用四行代码修复.. 使用更少的内存并通过更小的数组循环(要删除 emp)
    • @ravenx30 请仔细阅读我之前的评论。您的解决方案实际上通过 empDetails 执行 N 次循环,其中 N 是 empToRemove 的大小。循环中对“where”的每次 LINQ 调用都会导致遍历 empDetails 的所有元素。
    猜你喜欢
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 2021-03-24
    相关资源
    最近更新 更多