加快搜索并插入到concurrentbag c#

时间:2014-05-26 18:27:01

标签: c# multithreading performance list concurrency

我有一个问题,慢“建立”一个列表,我不知道如何加快它。 这是我的代码:

    private static ConcurrentBag<Classe<PojedynczeSlowa>> categoryClasses = new ConcurrentBag<Classe<PojedynczeSlowa>>();
    private const int howManyStudents = 20;
    private static int howManyClasses;
    private static EventWaitHandle[] ewhClass;
    private static List<Classe<Words>> deserializeClasses; 
//...
    public static void CreateCategoryClasses()
    {
        deserializeClasses  = Deserialize();
        howManyClasses = deserializeClasses.Count;
        ewhClass = new EventWaitHandle[howManyClasses];
        for (var i = 4; i >= 0; --i)
        {
            categoryClasses.Add(new Classe<PojedynczeSlowa>(((Categories) i).ToString()));
        }
        WaitCallback threadMethod = ParseCategories;
        ThreadPool.SetMaxThreads(howManyStudents, howManyClasses);

        for (var i = 0; i < howManyClasses; ++i)
        {
            ewhClass[i] = new EventWaitHandle(false, EventResetMode.AutoReset);
            ThreadPool.QueueUserWorkItem(threadMethod, i);
        }
        for (var i = 0; i < howManyClasses; ++i)
        {
            ewhClass[i].WaitOne();
        }

        var xmls = new XmlSerializer(typeof(List<Classe<PojedynczeSlowa>>)); //poprawić!!
        using (var sw = new StreamWriter(@"categoryClasses.xml"))
        {
            xmls.Serialize(sw, categoryClasses.ToList());
        }
    }

    private static void ParseCategories(object index)
    {
        int sum;
        var i = index as int?;

        if (deserializeClasses[i.Value].Category == Categories.PEOPLE.ToString())
        {
            foreach (var word in deserializeClasses[i.Value].Bag)
            {
                sum =
                    deserializeClasses.Count(
                        clas =>
                            clas.Bag.Where(x => clas.Category == deserializeClasses[i.Value].Category)
                                .Contains(word));
                if (!categoryClasses.ElementAt(0).Bag.Contains(new PojedynczeSlowa(word.Word, sum)))
                {
                    categoryClasses.ElementAt(0)
                        .Bag.Add(new PojedynczeSlowa(word.Word,
                            Convert.ToDouble(sum)/
                            Convert.ToDouble(deserializeClasses.Count(x => x.Category == deserializeClasses[i.Value].Category))));
                }
            }
        }
//rest of the code which adds elements to the list on other indexes.
        ewhClass[(i).Value].Set();
    }

我可以补充一点:

deserializeClasses包含类“Word”,

的大约18550个元素,并且任何这些元素(“Word”)包含字符串和int的列表,此列表的平均大小约为200-250个元素。我使用.net 4.5.1 谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

一些事情(我没有足够的代表发表评论,所以我的评论也在这里发表)......

1)类定义非常有用。例如,你有 if (!categoryClasses.ElementAt(0).Bag.Contains(new PojedynczeSlowa(word.Word, sum)))
如果你没有覆盖object.Equals(你呢?),这将永远不会成真。此外,更难以了解样本不完整的情况 2)你的代码
sum = deserializeClasses.Count(clas => clas.Bag.Where(x => clas.Category == deserializeClasses[i.Value].Category).Contains(word));
完全没有使用x。考虑
sum = deserializeClasses.Count(clas => clas.Category == deserializeClasses[i.Value].Category && clas.Bag.Contains(word));
这避免了很多潜在的枚举,即使最坏的情况成本保持不变,也可以加快平均成本 3)词典是你的朋友。考虑制作一些临时字典,这些字典由您要检查的内容编制索引。我很难弄清楚你想要做什么(见评论1),但我猜你可以节省相当多的性能成本,尤其是Contains()调用,使用Dictionary。登记/> 4)我不确定多线程会在这里为你节省一些东西。我猜它会让事情变慢,因为这看起来是CPU绑定的,你正在通过线程切换增加CPU开销。

我会帮忙解决一些代码,但是我有点急,没有时间猜测剩下的代码,以便编译所有内容。