===前情提要===
目前在重整数据库的资料(约2,800万笔),所以必须一笔一笔爬
资料爬出来后会做两种处理,再建立新的数据库
数据库使用mongodb,先把整个collection做findall,再丢入foreach的循环去跑
用了两个foreach,为省略版面,以下code只写一个foreach作为范本
===方案A,单执行绪===
var result = coll.FindAll();
foreach(var doc in result)
{
工作!();
}
结果:
工作A处理效能:20笔/秒
工作B处理效能:10笔/秒
慢慢做内存跟CPU都不炸
===方案B,多执行绪===
var result = coll.FindAll();
foreach(var doc in result)
{
Task Task_CheckData = Task.Factory.StartNew(() =>
{
工作!();
});
}
结果:
工作A处理效能:900up笔/秒,持续加速
工作B处理效能:15up笔/秒,缓慢加速,数据库效能都被工作A吃掉了
炉~心~超~载~啦~
由于一直生出新的Task,但程式又没有适当的释放资源,导致内存持续上升
吃完所有实体内存后执行速度很缓慢,而且也没有释放内存的情况
===方案C,多执行绪+Dispose===
var result = coll.FindAll();
foreach(var doc in result)
{
Task Task_CheckData = Task.Factory.StartNew(() =>
{
工作!();
});
Task_CheckData.Wait();
Task_CheckData.Dispose();
}
结果:
工作A处理效能:20笔/秒
工作B处理效能:10笔/秒
体悟心灵祥和ˊㄇˋ
已经变成单执行绪的形状了
===方案D,多执行绪+ContinueWith,失败===
var result = coll.FindAll();
foreach(var doc in result)
{
Task Task_CheckData = Task.Factory.StartNew(() =>
{
工作!();
});
Task_CheckData.ContinueWith(antecendent =>
{
Task_CheckData_Each.Dispose();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
结果:
程式整个卡住不跑...
D方案比C方案早生出来
因为失败了所以先前没key
===问题结论===
大概出在Task的使用上
但喂狗后还是没发现比较好的解决方案
或许是我关键字下错QQ
请版上先知指教,谢谢
作者:
ssccg (23)
2016-07-15 15:13:00Parallel.ForEach?顺便说一下你方案C不叫多执行绪+dispose,你用了Wait()就是把目前的执行绪block到该Task完成后才跑下一个StartNew同时间就是只有单执行绪
难怪会被打回原形,还是得等task完成工作感谢提点!请问Parallel.ForEach,建议与Task并用吗?
作者:
ssccg (23)
2016-07-15 15:34:00最上面说错了,Parallel.ForEach跟Task是一样的...应该要先看方案B问题是出在哪,应该不是Task没有释放资源
或许是新增Task的速度大于Task执行完成的速度?但是task不像threadpool有数量的限制...
作者:
ssccg (23)
2016-07-15 15:38:00如果是新增速度大于完成速度,可能要调整已经在等待执行的Task数量太多,就先暂停新增的动作Task底层应该还是用ThreadPool做,所以应该不是Thread太多是排在queue上的Task太多
开几个task持续处理资料不要新开就行了吧~ 你这方式感觉额外负担太大了...@@
作者:
enonrick (EnonRick)
2016-07-15 15:54:00task 无限增生? 就算你程式够强吃得下,你还是会卡在IO导致整个程序卡住。最好的作法是把资料分成chunk,每个chunk 限制笔数,把chunk丢到 thread 去跑,再视情况调整thread 的数量但就算方案A ,一秒只有20笔,是不是有什么误会..
作者:
Litfal (Litfal)
2016-07-15 16:35:00你的bound在数据库(I/O bound),用多执行续不太会增加效率一些情况反而会更差,就好像你同时开好几个执行续去读同一颗硬盘的资料一样这种情况要做多执行续优化,不应该用件数(平行)去切割,而是要依工作类型(垂直)去切。
同意楼上,如果你一个工作内容要存取4次DB,应该有其他方式可以减少DB存取的次数,有机会提高更多效率
作者:
sorkayi (寻找奶昔)
2016-07-16 09:46:00Parallel.For 速度超快的 越多核心越快