在单元测试中使用语句的性能影响

时间:2013-02-05 11:33:28

标签: c# wcf unit-testing

我在本地托管了一个WCF服务,公开了一个基本方法,它返回传递给它的字符串值。

我还有一个单元测试,我尝试将服务调用10000次,并监控完成调用所需的时间。

我的测试中使用声明的位置至关重要,如果放错了会产生很大的不同,但我不明白为什么会这样。

示例1:(35秒)

    [TestMethod]
    public void TestGetDataOutsideUsing()
    {
        const int count = 10000;
        var operations = new List<int>();
        for (var i = 0; i < count; i++)
            operations.Add(i);
        using (var proxy = new BasicHttpServiceClient())
        {
            var timer = Stopwatch.StartNew();
            System.Threading.Tasks.Parallel.ForEach(operations, x => { proxy.GetData(x.ToString(CultureInfo.InvariantCulture)); });
            timer.Stop();
            Console.WriteLine("{0:###0.0000000} ms", timer.ElapsedMilliseconds);
            Console.WriteLine("{0:###0.0000000} per millisecond", (count / (decimal)timer.ElapsedMilliseconds));
            Console.WriteLine("{0:###0.0000000} per second", (count / ((decimal)timer.ElapsedMilliseconds / 1000)));
            Console.WriteLine("{0:###0.0000000} per minute", (count / ((decimal)timer.ElapsedMilliseconds / 1000 / 60)));
        }
    }

示例2:(6.2秒)

    [TestMethod]
    public void TestGetDataInsideUsing()
    {
        const int count = 10000;
        var operations = new List<int>();
        for (var i = 0; i < count; i++)
            operations.Add(i);
        var timer = Stopwatch.StartNew();
        System.Threading.Tasks.Parallel.ForEach(operations, x =>
            {
                using (var proxy = new BasicHttpServiceClient())
                {
                    proxy.GetData(x.ToString(CultureInfo.InvariantCulture));
                }
            });
        timer.Stop();
        Console.WriteLine("{0:###0.0000000} ms", timer.ElapsedMilliseconds);
        Console.WriteLine("{0:###0.0000000} per millisecond", (count / (decimal)timer.ElapsedMilliseconds));
        Console.WriteLine("{0:###0.0000000} per second", (count / ((decimal)timer.ElapsedMilliseconds / 1000)));
        Console.WriteLine("{0:###0.0000000} per minute", (count / ((decimal)timer.ElapsedMilliseconds / 1000 / 60)));
    }

第一个和第二个例子之间的唯一区别是using语句的位置。我原本以为在ForEach中使用using语句会花费更长时间,但事实证明不然。

为什么会这样,以上哪个例子是测试这个的准确方法?我可能以错误的方式进行这项测试吗?

我想做的就是对我的服务进行10000次并发调用,看看需要多长时间。

2 个答案:

答案 0 :(得分:4)

在第一个例子中,有一个Proxy个对象;在第二个示例中,有多个Proxy个对象。

我认为这与using语句没有直接关联,而是如何使用它。在第一个示例中,Proxy对象成为并行操作的瓶颈。

答案 1 :(得分:2)

这是两件非常不同的事情:

  • 在第一个示例中,您在一个代理对象上运行多个线程,这有效地序列化了处理 1 并破坏了并行性。
  • 在第二个示例中,每个线程都有自己的代理对象,允许它独立于(并同时)运行其他线程。

工作量更不等于 2 ,但第二个例子更快完成,因为更多的工作可以并行完成。


1 我假设那里有一个锁,否则你就有竞争条件。

2 忽略创建所有这些代理的成本。