我有一个问题,慢“建立”一个列表,我不知道如何加快它。 这是我的代码:
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 谢谢你的帮助!
答案 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开销。
我会帮忙解决一些代码,但是我有点急,没有时间猜测剩下的代码,以便编译所有内容。