Есть ли встроенная поддержка в TPL (Task-Parallel-Library) для операций дозирования?Parallel Operation Batching
Я недавно играл с обычной для выполнения замены символов на массив символов с помощью таблицы поиска, т.е. транслитерации:
for (int i = 0; i < chars.Length; i++)
{
char replaceChar;
if (lookup.TryGetValue(chars[i], out replaceChar))
{
chars[i] = replaceChar;
}
}
я мог видеть, что это может быть тривиальным распараллеливание, так прыгнул с первой колото который я знал, что будет выполнять хуже задачи были слишком мелкозернистыми:
Parallel.For(0, chars.Length, i =>
{
char replaceChar;
if (lookup.TryGetValue(chars[i], out replaceChar))
{
chars[i] = replaceChar;
}
});
затем я переделан алгоритм использовать группирование так, чтобы работа могла быть фрагментированной на разные потоки менее мелкозернистых партий. Это использовало потоки, как ожидалось, и я получил некоторую линейную скорость.
Я уверен, что в TPL должна быть встроенная поддержка для дозирования. Каков синтаксис и как его использовать?
const int CharBatch = 100;
int charLen = chars.Length;
Parallel.For(0, ((charLen/CharBatch) + 1), i =>
{
int batchUpper = ((i + 1) * CharBatch);
for (int j = i * CharBatch; j < batchUpper && j < charLen; j++)
{
char replaceChar;
if (lookup.TryGetValue(chars[j], out replaceChar))
{
chars[j] = replaceChar;
}
}
});
Update
После использования @ ответ Оливера и замена Parallel.For
с Parallel.ForEach and a Partitioner код выглядит следующим образом:
const int CharBatch = 100;
Parallel.ForEach(Partitioner.Create(0, chars.Length, CharBatch), range =>
{
for (int i = range.Item1; i < range.Item2; i++)
{
char replaceChar;
if (lookup.TryGetValue(chars[i], out replaceChar))
{
chars[i] = replaceChar;
}
}
});
Спасибо за ссылку, но у вас есть конкретный ответ на мой вопрос? –
@chibacity: просто обновил ответ. – Oliver
Это замечательное спасибо. Работает отлично и очень хороший API тоже :) Я обновил свой вопрос на примере, основанном на вашем ответе. –