C# 提高嵌套循环的性能

C# 提高嵌套循环的性能,c#,multithreading,parallel-processing,delegates,multiprocessing,C#,Multithreading,Parallel Processing,Delegates,Multiprocessing,对于这个例子,我简化了我的程序,所以我基本上加载一个文件,并将文件中的值添加到一个列表中 IList<string> MyList = new List<string>(); Main () { foreach(Row r in InputFile) { foreach(Cell c in r) { AddToList(c.Value); } } } public void AddToTheL

对于这个例子,我简化了我的程序,所以我基本上加载一个文件,并将文件中的值添加到一个列表中

IList<string> MyList = new List<string>();

Main () 
{
   foreach(Row r in InputFile)
   {
      foreach(Cell c in r)
      {
          AddToList(c.Value);
      }
   }
}

public void AddToTheList(string value)
{
   MyList.Add(value);  
}
IList MyList=new List();
主要()
{
foreach(InputFile中的r行)
{
foreach(r中的c单元)
{
AddToList(c.值);
}
}
}
public void AddToTheList(字符串值)
{
MyList.Add(值);
}
我希望加快循环的处理速度,我不关心添加值的顺序

我正在考虑并行运行循环和/或将AddToTheList方法视为异步的fire-and-forget方法


让代码使用服务器处理能力并加快文件处理总时间的最简单方法是什么?

这取决于具体情况。如果解析行和单元格并向列表中添加值很简单,那么并行处理对您没有帮助-您将受到I/O限制,这比CPU慢得多


但是,如果解析行需要时间,并且您不是真正地添加到
列表中,而是执行更复杂的操作,那么您可以从文件中读取行,然后并行处理这些行—只需为它们预先分配内存(
列表让您这样做)并并行访问每行的
列表
位置。

视情况而定。如果解析行和单元格并向列表中添加值很简单,那么并行处理对您没有帮助-您将受到I/O限制,这比CPU慢得多


但是,如果解析行需要时间,并且您不是真正地添加到
列表中,而是执行更复杂的操作,那么您可以从文件中读取行,然后并行处理这些行—只需为它们预先分配内存(
列表让您这样做)并并行访问每一行的
列表
位置。

更新:如果内部循环足够重,导致此任务CPU受限(而非IO受限),则可以使用
parallel.ForEach
对循环进行分区。下面是一个例子:

Parallel.ForEach(InputFile, row =>
{
    foreach(Cell c in row)
        AddToList(c.Value);
});
或者,更改
AddToList
签名以返回所需的值,并改用PLINQ

MyList = InputFile.AsParallel()
                  .SelectMany(row => row.AsParallel()
                                        .Select(cell => TransformCell(cell.Value))
                  .ToList();

public string TransformCell(string value)
{
   return value + " something";
}
使
AddToTheList
成为一个fire-and-forget异步方法几乎肯定不是一个好的选择。该方法引发的异常将无法处理,根据您使用的框架,这些异常可能会使应用程序崩溃


并行调用AddToTheList是不好的-此任务是IO限制的。 瓶颈在于从磁盘读取数据的速度

并行化磁盘访问也不好。让两个或多个线程读取同一个文件不会更快——无论如何,它们都必须轮流执行。看到这个答案了吗

使用尽可能多的线程


更新:如果内部循环足够重,足以使此任务绑定CPU(而不是IO),则可以使用
Parallel.ForEach
对循环进行分区。下面是一个例子:

Parallel.ForEach(InputFile, row =>
{
    foreach(Cell c in row)
        AddToList(c.Value);
});
或者,更改
AddToList
签名以返回所需的值,并改用PLINQ

MyList = InputFile.AsParallel()
                  .SelectMany(row => row.AsParallel()
                                        .Select(cell => TransformCell(cell.Value))
                  .ToList();

public string TransformCell(string value)
{
   return value + " something";
}
使
AddToTheList
成为一个fire-and-forget异步方法几乎肯定不是一个好的选择。该方法引发的异常将无法处理,根据您使用的框架,这些异常可能会使应用程序崩溃


并行调用AddToTheList是不好的-此任务是IO限制的。 瓶颈在于从磁盘读取数据的速度

并行化磁盘访问也不好。让两个或多个线程读取同一个文件不会更快——无论如何,它们都必须轮流执行。看到这个答案了吗

使用尽可能多的线程


您所说的
使用服务器是什么意思?
?这个问题似乎离题了,因为它需要对性能进行代码检查-checkout codereview.stackexchange.com输入文件的类型是什么?
?输入有多大?@rhughes抱歉,输入错误,我的坏你所说的
使用服务器是什么意思?
?这个问题似乎离题了,因为它需要对性能进行代码检查-checkout codereview.stackexchange.com
输入文件的类型是什么?输入有多大?@rhughes抱歉,我的错