与实体框架并行。与启动多个可执行文件相比,性能是巨大的,为什么?

时间:2012-02-10 14:43:00

标签: performance entity-framework frameworks entity parallel-processing

我想知道你们中间是否有人知道为什么我的表现很糟糕;

我想要实现的目标; 生成220万个文件。要创建每个文件,平均需要2-5个数据库调用。

我正在使用的服务器有24个核心和190GB的RAM。

我将需要生成的文件分成24批。

Whey我使用下面的代码,我的表现很糟糕。生成过程需要一个多小时。

Parrallel.ForEach(batches, batch => 
{
    using (var ctx = new MyContext())
    {
        for each(var file in batch.Files)
        {
            GenerateFile(file);
        }
    }
});

但是,当我确保我的程序收到一个参数,以便progam知道要生成哪个批处理,所以我不需要使用并行功能。如果我使用以下.bat文件执行每个批处理的程序;

START CaMaakEiBericht.exe \B1
START CaMaakEiBericht.exe \B2
...
START CaMaakEiBericht.exe \B24

它运行速度惊人!总生成过程不到15分钟! 此批处理文件还确保每个核心的CPU使用率约为90%。当我使用Parallel方法时,我只能获得30-40%的使用率。

有人对此有合理的解释吗?我对这个项目很满意,因为我最终有可能将.NET 4 Parallel库与EF结合使用,但不幸的是,它让我有点失望: - )

我个人有点怀疑EF是这里的瓶颈......当多个进程获取数据时,它是否会在内部缓存一些强加某些锁的内容?

启发我: - )

1 个答案:

答案 0 :(得分:4)

我不能说出为什么你的其他EXE文件运行良好,但我可以为你提供的代码提供建议。

您提到您将工作分成24批,然后在批次列表中使用ForEach。通过这种设置,我们的24个核心中的每一个都可以一次处理1个文件。我猜这是你的瓶颈。

如果你愿意的话,每个核心都可以做得更多。尝试这样的事情:

Parallel.ForEach(batches, batch => 
{
    Parallel.ForEach(batch.Files, file =>
    {
        using (var ctx = new MyContext())
        {
            GenerateFile(file);
        }     
    }
});

或者您可以完全摆脱批次并为其提供完整的文件列表。任务并行库将为您使用多个核心。

Parallel.ForEach(Files, file => 
{
    using (var ctx = new MyContext())
    {
        GenerateFile(file);
    }     
});

你可能已经知道了这一点,但请记住context is not thread safe,所以你必须在最里面的Parallel.ForEach结构中创建一个新的。