c# - How to reduce the execution time in Parallel.ForEach function? -
code:
parallel.foreach( infomap, map => { var workitem = map.workitem; var parentinviews = viewmaps; var workbenchitem = map.workbenchitem; string linktype = string.empty; workitemlinkcollection linkedworkitems = workitem.workitemlinkhistory; if (linkedworkitems != null && linkedworkitems.count > 0) linktype = linkedworkitems[0].linktypeend.linktype.referencename; else if (workitem != null) linktype = workitem.store.workitemlinktypes.linktypeends["parent"].linktype.referencename; if (!string.isnullorempty(linktype)) { var viewmap = parentinviews.firstordefault(); if (viewmap != null) { var linkname = linktype; var childtype = viewmap.childtype; ilinkitem itm = factory.buildlinkitem(linkname, workbenchitem, workbenchitem); lock (addparents) { addparents.add(itm); } } } });
factory.buildlinkitem
definition:
public static ilinkitem buildlinkitem(string linkname, iworkbenchitem parent, iworkbenchitem child) { return new linkitem { linkname = linkname ?? string.empty, child = child, parent = parent }; }
totally 658 items
present , takes 10 seconds execute above parallel.foreach
function.
is possible reduce execution time , if so, please suggest me solution. thanks.
note: apart parallel.foreach
, if alternate method there increase performance , reduce execution time also, please suggest. thanks.
your problem in lock
statement. mutex
mechanism behind extremely performance expensive compared other synchronization mechanisms. i'm gonna bet 99.99% of 10 seconds, code spends locking , waiting in critical section. non-parallel select faster.
your have 2 options. first use .asparallel()
.select()
, .where()
instead of parallel.foreach
, adding collection inside lock. highly recommend this. way, synchronization between operation on different items handled automatically.
second option use kind of concurrent collection exist in .net 4 instead of locking , normal collection. collections specially optimized quick adding of items, threadsafe.
this little hack, how convert asparallel
:
infomap.asparallel().select( map => { var workitem = map.workitem; var parentinviews = viewmaps; var workbenchitem = map.workbenchitem; string linktype = string.empty; workitemlinkcollection linkedworkitems = workitem.workitemlinkhistory; if (linkedworkitems != null && linkedworkitems.count > 0) linktype = linkedworkitems[0].linktypeend.linktype.referencename; else if (workitem != null) linktype = workitem.store.workitemlinktypes.linktypeends["parent"].linktype.referencename; if (!string.isnullorempty(linktype)) { var viewmap = parentinviews.firstordefault(); if (viewmap != null) { var linkname = linktype; var childtype = viewmap.childtype; ilinkitem itm = factory.buildlinkitem(linkname, workbenchitem, workbenchitem); return new {item = itm, filter=true}; } } return new {item = (ilinkitem)null, filter=false}; }) .where(x=>x.filter) .select(x=>x.item) .tolist();
Comments
Post a Comment