异步比同步慢

Saj*_*idQ -1 c# asynchronous task-parallel-library async-await .net-4.5

我一直在进行异步调用,发现方法的异步版本比同步版本运行慢得多。谁能评论我可能缺少的东西。谢谢。

统计

同步方法时间为00:00:23.5673480

异步方法时间为00:01:07.1628415

每个呼叫返回的总记录/条目= 19972

下面是我正在运行的代码。

--------------------测试课程----------------------

[TestMethod]
public void TestPeoplePerformanceSyncVsAsync()
{
    DateTime start;
    DateTime end;

    start = DateTime.Now;
    for (int i = 0; i < 10; i++)
    {
    using (IPersonRepository repository = kernel.Get<IPersonRepository>())
    {
        IList<IPerson> people1 = repository.GetPeople();
        IList<IPerson> people2 = repository.GetPeople();
    }
    }
    end = DateTime.Now;
    var diff = start - end;
    Console.WriteLine(diff);

    start = DateTime.Now;
    for (int i = 0; i < 10; i++)
    {
    using (IPersonRepository repository = kernel.Get<IPersonRepository>())
    {
        Task<IList<IPerson>> people1 = GetPeopleAsync();
        Task<IList<IPerson>> people2 = GetPeopleAsync();
        Task.WaitAll(new Task[] {people1, people2});
    }
    }
    end = DateTime.Now;
    diff = start - end;
    Console.WriteLine(diff);
}

private async Task<IList<IPerson>> GetPeopleAsync()
{
    using (IPersonRepository repository = kernel.Get<IPersonRepository>())
    {
    return await repository.GetPeopleAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

--------------------------储存库----------------------- -----

    public IList<IPerson> GetPeople()
    {
        List<IPerson> people = new List<IPerson>();
        using (PersonContext context = new PersonContext())
        {
            people.AddRange(context.People);
        }
        return people;
    }

    public async Task<IList<IPerson>> GetPeopleAsync()
    {
        List<IPerson> people = new List<IPerson>();
        using (PersonContext context = new PersonContext())
        {
            people.AddRange(await context.People.ToListAsync());
        }
        return people;
    }
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 5

于是我们做过了一堆的问题在这里,所以我只想说了蝙蝠的权利,这是不打算成为一个详尽的清单。

首先,该不同步不严格,以提高性能。在某些情况下,它可以用来提高性能,但这不一定是其目标。例如,它也可以用于使UI保持响应。 并行化通常用于提高性能,但是并行化和异步并不等效。最重要的,并行化会产生开销。您正在花费时间创建线程,安排线程,在它们之间同步数据等。并行执行某些操作的好处可能会或可能不会超过此开销。如果不是这样,同步解决方案可能会更有效。

接下来,您的“异步”示例并非“一路向上”异步。您正在调用WaitAll循环内的任务。为了使示例正确地异步,人们希望看到它一直到单个操作(即某种形式的消息循环)都是异步的。

其次,在异步和同步庄园中,两者并非完全相同。他们在做不同的事情,这显然会影响性能:

  • 您的“异步”解决方案将创建3个存储库。您的同步解决方案将创建一个。这里会有一些开销。
  • GetPeopleAsync获取一个列表,然后将所有项目从列表中拉出,然后将它们放入另一个列表中。那是不必要的开销。

然后基准测试就会出现问题:

  • 您正在使用DateTime.Now,它不是用于计时操作需要多长时间。例如,它的精度不是特别高。您应该使用a StopWatch来计时代码需要花费多长时间。
  • 您并没有执行太多的迭代。变体有很多机会影响此处的结果。
  • 您没有考虑到前几个代码段会花费更长的时间这一事实。JITter需要“热身”。
  • 垃圾收集可能会影响您的时间安排,即,第一次测试中创建的对象最终可能在第二次测试中被清除。