我有多个枚举器来枚举平面文件。我最初在 Parallel Invoke 中有每个枚举器,每个 Action 都添加到 aBlockingCollection<Entity>
中,并且集合返回 ConsumingEnumerable();
public interface IFlatFileQuery
{
IEnumerable<Entity> Run();
}
public class FlatFile1 : IFlatFileQuery
{
public IEnumerable<Entity> Run()
{
// loop over a flat file and yield each result
yield return Entity;
}
}
public class Main
{
public IEnumerable<Entity> DoLongTask(ICollection<IFlatFileQuery> _flatFileQueries)
{
// do some other stuff that needs to be returned first:
yield return Entity;
// then enumerate and return the flat file data
foreach (var entity in GetData(_flatFileQueries))
{
yield return entity;
}
}
private IEnumerable<Entity> GetData(_flatFileQueries)
{
var buffer = new BlockingCollection<Entity>(100);
var actions = _flatFileQueries.Select(fundFileQuery => (Action)(() =>
{
foreach (var entity in fundFileQuery.Run())
{
buffer.TryAdd(entity, Timeout.Infinite);
}
})).ToArray();
Task.Factory.StartNew(() =>
{
Parallel.Invoke(actions);
buffer.CompleteAdding();
});
return buffer.GetConsumingEnumerable();
}
}
然而,经过一些测试后发现,下面的代码更改速度提高了大约 20-25%。
private IEnumerable<Entity> GetData(_flatFileQueries)
{
return _flatFileQueries.AsParallel().SelectMany(ffq => ffq.Run());
}
代码更改的问题在于,它要等到所有平面文件查询都被枚举出来,然后才会返回可以枚举和生成的全部内容。
是否有可能在上面的代码中以某种方式让步以使其更快?
我应该补充一点,所有平面文件查询的组合结果最多可能只有 1000 个左右的实体。
编辑:将其更改为以下内容不会对运行时间产生影响。(R# 甚至建议回到原来的样子)
private IEnumerable<Entity> GetData(_flatFileQueries)
{
foreach (var entity in _flatFileQueries.AsParallel().SelectMany(ffq => ffq.Run()))
{
yield return entity;
}
}