1

当 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; }
    }

艾伦

4

3 回答 3

3

您可以将 your 转换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 的连接键。希望您的数据的性质不会成为问题。无论如何,我希望你明白了。

于 2013-09-05T02:35:25.470 回答
3

您可以尝试使用 Parallel 看看是否有帮助

List<SecurityInfo> listSecurityInfo = SecurityInfoMasterList.AsParallel.Where(c => 
    listClassiNode.Any(d => 
        c.SX == d.Exch && c.Instrument == d.Instrument)).ToList();
于 2013-09-05T02:23:18.530 回答
0

使用你的课程

在调试模式下运行大约需要 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)
                });
            }
        }
    }
于 2013-09-05T02:32:07.277 回答