c#多线程快速处理大量数据

时间:2016-11-22 13:32:41

标签: c# multithreading text

嘿,我在文本文件上有+15000000条记录 我需要处理它们的每一行 使用多线程将是有用的 有什么建议 ? 例如创建10000个线程并除以15000000/10000以给每个线程小数据量?

3 个答案:

答案 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函数,我确信它可以依赖于其他东西,比如并行设置。

相关问题