Есть некая коллекция или даже IEnumerable. Нужно создать новую коллекцию путем преобразования каждого элемента исходной коллекции(Map). При этом хочется распараллелить обработку через ThreadPool. Как это сделать красиво, в Nemerle-way стиле. Через Computation Expressions должно красиво получится, мне кажется.
Здравствуйте, Ka3a4oK, Вы писали:
KK>В Nemerle есть возможность использовать PLINQ?
Под .NET 4.0 — да.
Здравствуйте, Ka3a4oK, Вы писали:
H>>В .NET 4.0 можно использовать PLINQ.
KK>В Nemerle есть возможность использовать PLINQ?
Естественно. Это же просто библиотека.
Если PLINQ по каким-то причинам использовать не получится, то можно один из следующий самопалов использовать:
С использованием ComputationExpressions (надо добавить ссылку на сборки ComputationExpressions.Macros.dll и ComputationExpressions.dll):
public ParallelMap[TIn, TOut](this source : Seq[TIn], convert : TIn -> TOut) : Seq[TOut]
{
source.MapToArray(e => (comp async return convert(e)).Start()).MapToArray(_.Value)
}
Или прямо на базе пула:
public ParallelMap[TIn, TOut](this source : Seq[TIn], convert : TIn -> TOut) : Seq[TOut]
{
def actionDelegate : Func[TIn, TOut] = convert;
def results = source.MapToArray(a => actionDelegate.BeginInvoke(a, null, null));
def waitHandles = results.MapToArray(_.AsyncWaitHandle);
_ = Threading.WaitHandle.WaitAll(waitHandles);
results.MapToArray(actionDelegate.EndInvoke)
}
В догонку ParallelForEach:
public ParallelForEach[T](this source : Seq[T], action : T -> void) : void
{
def actionDelegate : Action[T] = action;
def waitHandles = source.MapToArray(a => actionDelegate.BeginInvoke(a, null, null).AsyncWaitHandle);
_ = Threading.WaitHandle.WaitAll(waitHandles);
}
Только учти, что выигрыш от распараллеливания подобным образом будет только, если распараллеливаемые участки кода выполняются относительно долго (не меньше десятых долей секунды). Иначе все уйдет в гудок (время будет тратиться на переключение контекста и прочую байду). Еще в вызываемых функциях не должно быт блокировок.