Effectiveness of using an expression in a unit test

I have a WCF service hosted locally, exposing a base method that returns a string value that you pass to it.

I also have a unit test where I try to call a service 10,000 times and I keep track of the time it takes for the calls to complete.

The position of my use statement in my test is critical and matters a lot if placed incorrectly, however I don't understand why this is happening.

Example 1: (35 seconds)

    [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)));
        }
    }

      

Example 2: (6.2 seconds)

    [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)));
    }

      

The only difference between the 1st and 2nd examples is the position of the using statement. I would have thought it would take longer to use the using statement inside ForEach, but it actually turned out differently.

Why is this, and which of the above examples is the exact way to test it? Perhaps I am wrong on this test?

All I want to do is make 10,000 concurrent calls to my service and see how long it takes.

+3


source to share


2 answers


In the first example, there is one object Proxy

; the second example has multiple objects Proxy

.



I think this is not directly related to the operator using

, but how it is used. In the first example, the object Proxy

becomes the bottleneck for the parallel operation.

+4


source


They are two different things:

  • In the first example, you are using multiple threads over a single proxy that effectively serializes handling 1 and destroys parallelism.
  • In the second example, each thread has its own proxy object that allows it to operate independently (and concurrently) from other threads.

The amount of work is more or less equal to 2, but the second example ends earlier because more work can be done in parallel.




1 I am assuming there is a blocking in there, otherwise you have a race condition.

2 Excluding the cost of creating all these proxies.

+2


source







All Articles