嘿,我在文本文件上有+15000000条记录 我需要处理它们的每一行 使用多线程将是有用的 有什么建议 ? 例如创建10000个线程并除以15000000/10000以给每个线程小数据量?
答案 0 :(得分:2)
您可以使用 Parallel Linq (PLinq):
var result = File
.ReadLines(@"C:\MyFile.txt")
.AsParallel()
//.AsOrdered() // if you want to preserve the order of file lines
.WithDegreeOfParallelism(10) // let's try 10 threads
.Select(line => ProcessLine(line)) // whatever
...
您可以轻松地将并行版本与顺序版本进行比较:注释掉.AsParallel()
和.WithDegreeOfParallelism(10)
或添加.AsSequential()
答案 1 :(得分:0)
您需要一个线程安全集合和一个并行循环。假设您将所有行读入线程安全列表,您可以这样使用它:
必需的命名空间:
using System.Collections.Concurrent;
using System.Threading.Tasks;
代码:
ConcurrentBag<string> items = new ConcurrentBag<string>(File.ReadLines(@"C:\input.txt"));
ParallelOptions po = new ParallelOptions() { MaxDegreeOfParallelism = 10 };
Parallel.ForEach<string>(items, po, line =>
{
ProcessItem(line);
});
答案 2 :(得分:0)
这实际上取决于你的线处理功能。 例如,我生成了5000000行的文件。然后我创建了3个函数:
void Seq()
{
foreach (var line in File.ReadLines(fname))
{
Process(line);
}
}
void Parallel1()
{
Parallel.ForEach(File.ReadLines(fname), line=>Process(line));
}
void Parallel2()
{
var list = new List<string>();
var tasks = new List<Task>();
foreach (var line in File.ReadLines(fname))
{
list.Add(line);
if (list.Count > 1000)
{
var local = list;
list = new List<string>();
tasks.Add(Task.Run(()=>local.ForEach(x=>Process(x))));
}
}
tasks.Add(Task.Run(()=>list.ForEach(x=>Process(x))));
Task.WaitAll(tasks.ToArray());
}
然后我想以这种方式测试它们:
void Main()
{
var sw = Stopwatch.StartNew();
Seq();
sw.Stop();
Console.WriteLine($"Seq {sw.Elapsed}");
sw = Stopwatch.StartNew();
Parallel1();
sw.Stop();
Console.WriteLine($"Parallel1 {sw.Elapsed}");
sw = Stopwatch.StartNew();
Parallel2();
sw.Stop();
Console.WriteLine($"Parallel2 {sw.Elapsed}");
}
我的处理功能非常快:
private void Process (string line)
{
for (var i = 0; i < 20; i++)
{
}
}
我得到了结果:
Seq 00:00:00.9817211
Parallel1 00:00:01.0199068
Parallel2 00:00:00.6581931 <- fastest
但是,如果我让我的功能更快
private void Process (string line)
{
for (var i = 0; i < 2; i++)
{
}
}
Seq 00:00:00.6474700 <- fastest
Parallel1 00:00:00.9247764
Parallel2 00:00:00.6642463
BUT2
如果我让功能变慢:
private void Process (string line)
{
for (var i = 0; i < 200; i++)
{
}
}
Seq 00:00:04.3995186
Parallel1 00:00:01.4569537 <- fastest
Parallel2 00:00:02.0348749
所以,没有正确的答案,哪个更快,至少取决于Process
函数,我确信它可以依赖于其他东西,比如并行设置。