【发布时间】:2019-05-14 08:29:41
【问题描述】:
公平警告:这是一个关于方法的问题,至少是良好实践...这里的问题不是语法,而是方法。
我必须非常快速地处理大量记录,并向消费者提供一组转换后的记录。我想知道是否有人对最有效的方法有实用的建议。
这是场景:
我需要执行一组相对简单的逻辑: 连接到数据库 -> 读取记录 -> 转换每条记录 -> 将输出记录提供给消费者
这个逻辑需要从一个库中获得——内部逻辑对消费者完全隐藏。 (消费者不知道发生了某种变换——他认为他只是在循环一堆对象)。
通常,我会使用这样的方法创建一个 IEnumerable 类:
public class TransformingReader<T> where T:class,new()
{
...
...
...
public IEnumerator<T> GetEnumerator()
{
var items = _connection<dynamic>.GetData();
foreach (var item in items)
{
T transformed = _complexTask.Transform(item);
yield return transformed;
}
}
}
(这里使用动态类只是为了说明)
使用上面的类,消费者:
foreach(var item in new TransformingReader<TransactionAnalysis>())
{
...
DoStuff(item);
...
}
事实:
我每天要处理数百万条记录 - 所以数量是个大问题。
用户 DoStuff() 函数需要一些时间才能完成。我无法预测他们的工作会有多复杂,但它肯定会比我的工作更密集。
我在一个相对受限的环境中工作 - 因此没有大量可用内存并且其他应用程序都在同一台机器上。所以,我需要负责任地行事。 (我没有在爷爷的笔记本电脑上运行——但我仍然需要编写不贪婪的合理代码)
想法:
我想尝试并行化 Transform() 函数,这样我就可以利用 DoStuff() 忙的时间来转换下一条记录。通过这种方式,希望我总是(经常?)在用户要求下一条记录时为新记录做好准备。
我希望将简单的 foreach 语法保留在消费者端。消费者无需知道我在幕后努力工作。
对于如何解决此类问题的任何想法将不胜感激。具体来说,是否有一种我不知道的模式可以帮助解决这个问题?
【问题讨论】:
标签: c# performance optimization parallel-processing