I'm working on some text parser logic and have IO and CPU bound operations.
In general what I do: read file -> process text, read file 2 -> process text 2... and so on.
What I can do is to make operations "process text" and "read file 2" executing at the same time in different tasks. However when I created tree of related tasks I noticed that PLINQ became slower than it was initially. Here is simplified example of code:
class Program { static int idx;
public static void Main()
{
idx = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10; i++)
{
// here I execute my function with PLINQ
FuncP();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
idx = 0;
sw.Start();
List<Task> tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
int iLocal = i;
Task tsk;
if (i > 0)
{
// next task depends on previous one
tsk = Task.Run(() =>
{
Task.WaitAll(tasks[iLocal - 1]);
// execute the same function
FuncP();
});
}
else // i = 0
{
// first task does not depend on other tasks
tsk = Task.Run(() =>
{
// execute the same function
FuncP();
});
}
tasks.Add(tsk);
}
tasks.Last().Wait();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
private static void FuncP()
{
Stopwatch sw1 = new Stopwatch();
sw1.Start();
Console.WriteLine(string.Format("FuncP start {0}", ++idx));
string s = new string('c', 2000);
s.AsParallel()
.ForAll(_ =>
{
for (int i = 0; i < 1000000; i++) ;
});
sw1.Stop();
Console.WriteLine(string.Format("FuncP end {0}, Elapsed {1}", idx, sw1.ElapsedMilliseconds));
}
}
Output is:
FuncP start 1
FuncP end 1, Elapsed 409
FuncP start 2
FuncP end 2, Elapsed 345
FuncP start 3
FuncP end 3, Elapsed 344
FuncP start 4
FuncP end 4, Elapsed 337
FuncP start 5
FuncP end 5, Elapsed 344
FuncP start 6
FuncP end 6, Elapsed 343
FuncP start 7
FuncP end 7, Elapsed 348
FuncP start 8
FuncP end 8, Elapsed 351
FuncP start 9
FuncP end 9, Elapsed 343
FuncP start 10
FuncP end 10, Elapsed 334
3504
FuncP start 1
FuncP end 1, Elapsed 5522 --> here is high execution time
FuncP start 2
FuncP end 2, Elapsed 368
FuncP start 3
FuncP end 3, Elapsed 340
FuncP start 4
FuncP end 4, Elapsed 347
FuncP start 5
FuncP end 5, Elapsed 351
FuncP start 6
FuncP end 6, Elapsed 347
FuncP start 7
FuncP end 7, Elapsed 353
FuncP start 8
FuncP end 8, Elapsed 337
FuncP start 9
FuncP end 9, Elapsed 341
FuncP start 10
FuncP end 10, Elapsed 345
12160
Sometimes it hangs on first run PLINQ in task, sometimes on second one, but with tasks it takes much more time that in loop.
Not sure I understand exactly the reason why FuncP
execution time is so high, could it be that AsParallel()
does not make it parellel due to lack of "free" threads in thread pool?
Can someone explain? Thanks in advance.