优化通用列表WHERE

时间:2013-09-05 02:14:07

标签: c# lambda generic-list

当SecurityInfoMasterList有大约11,000个项目而listClassiNode有大约750个项目时,下面的语句大约需要6秒来产生输出。

有没有其他方法可以达到相同的效果但性能更好?

List<SecurityInfo> listSecurityInfo = SecurityInfoMasterList.Where(c => 
    listClassiNode.Any(d => 
        c.SX == d.Exch && c.Instrument == d.Instrument)).ToList();

我一直在尝试使用for循环,但没有看到太多改进。

更新:

listClassiNode是一个列表

[Serializable]
     public class SecurityInfo
    {
    public string SecurityID { get; set; }
    public int SecurityTypeID { get; set; }
    public string Code { get; set; }
    public string SecurityName { get; set; }
    public int DB { get; set; }
    public string ExchangeName { get; set; }
    public DateTime FirstDate { get; set; }
    public int StatusCode { get; set; }
    public long GICS { get; set; }
    public string ICB { get; set; }
    public string Sector { get; set; }
    public string IndustryGroup { get; set; }
    public string Industry { get; set; }
    public string Instrument { get; set; }
    public string TypeDescription { get; set; }
    public string SX { get; set; }
    public string GUID { get; set; }
  }



[Serializable()]
    public class ClassificationNode
    {
        public string Exch { get; set; }
        public string Instrument { get; set; }
        public string Prefix { get; set; }
        public string Name { get; set; }
        public string Level { get; set; }
    }

艾伦

3 个答案:

答案 0 :(得分:3)

您可以尝试使用并行查看是否有帮助

List<SecurityInfo> listSecurityInfo = SecurityInfoMasterList.AsParallel.Where(c => 
    listClassiNode.Any(d => 
        c.SX == d.Exch && c.Instrument == d.Instrument)).ToList();

答案 1 :(得分:3)

您可以将listClassiNode转换为某种HashSet,以便查找O(1)而不是O(n)

var hash = new HashSet<string>(
    listClassiNode.Select(t => 
        string.Format("{0}_{1}", t.Exch, t.Instrument)).Distinct());

List<SecurityInfo> listSecurityInfo = SecurityInfoMasterList.Where(c => 
    hash.Contains(string.Format("{0}_{1}", c.SX, c.Instrument))
        .ToList();

上面有点笨拙,string.Format创建了一个用于HashSet的连接键。希望您的数据的性质是这样的,这不会是一个问题。无论如何,我希望你能得到这个想法。

答案 2 :(得分:0)

使用你的班级

在DEBUG模式下运行大约需要4到5秒

12,000 x 12,000而不是11,000 x 750

 class Program
    {
        static void Main(string[] args)
        {
            var listSecurityInfo = new List<SecurityInfo>();
            var listClassiNode = new List<ClassiNode>();

            initList(listSecurityInfo, listClassiNode);

            var sw = System.Diagnostics.Stopwatch.StartNew();
            var matched = listSecurityInfo.Where(c => listClassiNode.Any(d =>  c.SX == d.Exch && c.Instrument == d.Instrument)).ToList();
            sw.Stop();

            Console.WriteLine("took: " + sw.ElapsedMilliseconds + "ms matched: " +matched.Count());
            Console.Read();
        }

        private static void initList(List<SecurityInfo> listSecurityInfo, List<ClassiNode> listClassiNode)
        {
            var rnd = new Random();

            for (int i = 0; i < 12000; ++i)
            {
                listSecurityInfo.Add(new SecurityInfo()
                {
                    SX = new string(Convert.ToChar(rnd.Next(40, 125)), 4000),
                    Instrument = new string(Convert.ToChar(rnd.Next(40, 125)), 4000)
                });
            }

            for (int i = 0; i < 12000; ++i)
            {
                listClassiNode.Add(new ClassiNode()
                {
                    Exch = new string(Convert.ToChar(rnd.Next(40, 125)), 4000),
                    Instrument = new string(Convert.ToChar(rnd.Next(40, 125)), 4000)
                });
            }
        }
    }
相关问题