Showing posts with label Performance. Show all posts
Showing posts with label Performance. Show all posts

Sunday, 19 October 2014

Performance Series - How poor performance of HttpContent.ReadAsAsync can affect your API/site

Level [T2]

This has been a revelation - what I am about to reveal here, deeply surprised me - it might surprise you too. This post is mainly about consuming restful APIs using HttpClient and when the payload is JSON.

UPDATE: I got in touch with the ASP.NET team and they confirmed this as a performance bug which has now been fixed but the fix yet not available.

As you probably know performance and benchmarking is very close to my heart and I have been recently focusing on benchmarking a few APIs at work. One of my observations was that the Web APIs/Web Sites which have historically been IO-bound, they show sign of CPU strain and have become CPU-bound.

When you think logically about it, there is no magic here: by using async/await, you end up putting your CPU into some use unlike the old times when the threads are blocked waiting for the IO to return and CPU would be twiddling its thumb. However, I found the CPU overhead of the operations excessive so I set out to benchmark a few different scenarios.

Test Setup

Two APIs were created where one was using the other. These two APIs were part of the same cloud service which was deployed to two separate Medium (A2) web roles. I used 2 different deployments of the same code, one dependent upon version 4.0.30506.0 of the API and the ther one with the latest version which was 5.2.2. Difference between two versions of the Web API is the topic of another post, but the differences were not huge although newer versions showed improved performance.

API being called returns a customer with its orders. Every customer has between 1 to 3 orders and each order between 1-3 items. On the long run, these randomisation gets evened out. Each document returned is between 1-2 KB. So the more superficial API, for every customer, makes one call to get the customer and for each customer will separately call the deeper API once for each order. Then it combines the result and sends back the response. Both APIs are deployed in the same Azure Data Centre.

You can find the whole code at GitHub. The code takes 4 different approaches as below:

public class CustomerController : ApiController
{
    public FullCustomer GetSync(int id)
    {
        var webClient = new WebClient();
        var customerString = webClient.DownloadString(BuildUrl(id));
        var customer = JsonConvert.DeserializeObject<Customer>(customerString);
        var fullCustomer = new FullCustomer(customer);
        var orders = new List<Order>();
        foreach (var orderId in customer.OrderIds)
        {
            var orderString = webClient.DownloadString(BuildUrl(id, orderId));
            var order = JsonConvert.DeserializeObject<Order>(orderString);
            orders.Add(order);
        }
        fullCustomer.Orders = orders;
        return fullCustomer;
    }

    public async Task<FullCustomer> GetASync(int id)
    {
        var webClient = new WebClient();
        var customerString = await webClient.DownloadStringTaskAsync(BuildUrl(id));
        var customer = JsonConvert.DeserializeObject<Customer>(customerString);
        var fullCustomer = new FullCustomer(customer);
        var orders = new List<Order>();
        foreach (var orderId in customer.OrderIds)
        {
            var orderString = await webClient.DownloadStringTaskAsync(BuildUrl(id, orderId));
            var order = JsonConvert.DeserializeObject<Order>(orderString);
            orders.Add(order);
        }
        fullCustomer.Orders = orders;
        return fullCustomer;
    }

    public async Task<FullCustomer> GetASyncWebApi(int id)
    {
        var httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); 
        var responseMessage = await httpClient.GetAsync(BuildUrl(id));
        var customer = await responseMessage.Content.ReadAsAsync<Customer>();
        var fullCustomer = new FullCustomer(customer);
        var orders = new List<Order>();
        foreach (var orderId in customer.OrderIds)
        {
            responseMessage = await httpClient.GetAsync(BuildUrl(id, orderId));
            var order = await responseMessage.Content.ReadAsAsync<Order>();
            orders.Add(order);
        }
        fullCustomer.Orders = orders;
        return fullCustomer;
    }

    public async Task<FullCustomer> GetASyncWebApiString(int id)
    {
        var httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); 
        var responseMessage = await httpClient.GetAsync(BuildUrl(id));
        var customerString = await responseMessage.Content.ReadAsStringAsync();
        var customer = JsonConvert.DeserializeObject<Customer>(customerString);
        var fullCustomer = new FullCustomer(customer);
        var orders = new List<Order>();
        foreach (var orderId in customer.OrderIds)
        {
            responseMessage = await httpClient.GetAsync(BuildUrl(id, orderId));
            var orderString = await responseMessage.Content.ReadAsStringAsync();
            var order = JsonConvert.DeserializeObject<Order>(orderString);
            orders.Add(order);
        }
        fullCustomer.Orders = orders;
        return fullCustomer;
    }

    private string BuildUrl(int customerId, int? orderId = null)
    {
        string baseUrl = string.Format("http://{0}:8080/api/customer/{1}", Request.RequestUri.Host, customerId);
        return orderId.HasValue
            ? string.Format("{0}/order/{1}", baseUrl, orderId.Value)
            : baseUrl;
    }

}
So as you can see, we use 4 different methods:

1) Using WebClient in the sync fashion
2) Using WebClient in the async fashion
3) Using HttpClient in the async fashion with ReadAsAsync on HttpContent
4) Using HttpClient in the async fashion with reading content as string and then using JsonConvert to deserialise

I used SuperBenchmarker to invoke the main API which gathers the data from the other API. I used the tool within the same Azure Data Centre from another machine (none of the APIs) to make the tests more realistic yet eliminate network idiosyncrasies.

I used 5000 requests with concurrency of 10 - although I tried other number as well which did not make any material difference in the results.

Results

Here is the result for scenario 1 (sync using WebClient):

TPS:    394 (requests/second)
Max:    199ms
Min:    8ms
Avg:    25ms

50%     below 24ms
60%     below 25ms
70%     below 27ms
80%     below 28ms
90%     below 30ms
95%     below 32ms
98%     below 36ms
99%     below 55ms
99.9%   below 185ms


The result for scenario 2 (Async using WebClient) usually shows better throughput but higher CPU

TPS:    485 (requests/second)
Max:    291ms
Min:    5ms
Avg:    20ms

50%     below 19ms
60%     below 21ms
70%     below 23ms
80%     below 25ms
90%     below 27ms
95%     below 29ms
98%     below 32ms
99%     below 36ms
99.9%   below 284ms

The CPU difference is not huge and can be explained by the increase throughput:

CPU usage during Scenario 1 and 2

Now what surprised me greatly was the result of the third scenario (using HttpContent.ReadAsAsync<T>). Apart from CPU of 100% and signs of queueing, here is the result:

TPS:    41 (requests/second)
Max:    12656ms
Min:    26ms
Avg:    240ms

50%     below 170ms
60%     below 178ms
70%     below 187ms
80%     below 205ms
90%     below 256ms
95%     below 296ms
98%     below 370ms
99%     below 3181ms
99.9%   below 12573ms

Yeah, shocking. The diagram below compares CPU usage between scenario 1 and 3:

CPU usage in scenario 1 (arrow) and 3 (box)

Scenario 4 is definitely better and is not too far from scenario 1 and 2:

TPS:    230 (requests/second)
Max:    7068ms
Min:    7ms
Avg:    43ms

50%     below 20ms
60%     below 22ms
70%     below 24ms
80%     below 26ms
90%     below 29ms
95%     below 34ms
98%     below 110ms
99%     below 144ms
99.9%   below 7036ms

The CPU usage is around 80% and definitely worse that scenario 1 and 2 (which requires further analysis).

Analysis

Where is the problem? It appears that JSON Deserialization when reading from a stream is not efficient. It is possible that the JSON Deserialization has to optimise for memory efficiency rather than CPU efficiency since when the whole string is passed, it is surely much faster. 

Profiling proves that the problem is indeed JSON Deserialization:

Profiling scenario 3 is showing that the most of the CPU time is spent in JSON Deserialisation

So in order to prove that, we do not have to invoke an API. The whole operation can be done inside a Console application. So I used the same code that was generating customers and orders. Here I am comparing

private static void Main(string[] args)
{
    const int TotalRun = 10*1000;

    var customerController = new CustomerController();
    var orderController = new OrderController();
    var customer = customerController.Get(1);

    var orders = new List<Order>();
    foreach (var orderId in customer.OrderIds)
    {
        orders.Add(orderController.Get(1, orderId));
    }

    var fullCustomer = new FullCustomer(customer)
    {
        Orders = orders
    };

    var s = JsonConvert.SerializeObject(fullCustomer);
    var bytes = Encoding.UTF8.GetBytes(s);
    var stream = new MemoryStream(bytes);
    var content = new StreamContent(stream);

    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            
    var stopwatch = Stopwatch.StartNew();
    for (int i = 1; i < TotalRun+1; i++)
    {
        var a = content.ReadAsAsync<FullCustomer>().Result;
        if(i % 100 == 0)
            Console.Write("\r" + i);
    }
    Console.WriteLine();
    Console.WriteLine(stopwatch.Elapsed);

    stopwatch.Restart();
    for (int i = 1; i < TotalRun+1; i++)
    {
        var sa = content.ReadAsStringAsync().Result;
        var a = JsonConvert.DeserializeObject<FullCustomer>(sa);
        if (i % 100 == 0)
            Console.Write("\r" + i);
    }
    Console.WriteLine();
    Console.WriteLine(stopwatch.Elapsed);

    Console.Read();

}

As expected, the result shows uncomparable difference, in the order of ~120:

10000
00:00:06.2345493
10000
00:00:00.0509763

So this result basically confirms what we have seen. I will get in touch with James Newton King and try to shed more light on the subject.

Conclusion

HttpContent.ReadAsAsync on JSON payloads is really slow - in the order of 120x compared to JsonConvert. I guess it might to do with the memory efficiency of reading from streams (keeping memory footprint at zero)  but that is a guess and I have been in touch with James Newton King (creator of Json.Net) to get to the bottom of it.

For the meantime, if you know your content is not going to be huge and always in JSON, you might as well forget about content negotiation and read it as a string and then use JsonConvert to deserialize.

Thursday, 16 October 2014

SuperBenchmarker v0.4 released

Level [T2]

This is a quick shoutout on the release of version 0.4 of SuperBenchmarker, a Web and/or Web API performance benchmarking command line tool for Windows.

You might have heard about and used Apache Benchmark (ab.exe) in the past which is a very useful tool but on Windows it is very limited (e.g cannot make POST, PUT, etc requests and only supports GET). SuperBenchmarker (sb.exe) supports PUT, DELETE, POST or any arbitrary method and allows you to parameterise the URL and headers using a data file, a .NET DLL plugin and the new feature is the randomisation feature which removes the need for any setup when all needed is random data.


Getting started

The best way to get SuperBenchmarker is to use awesome Chocolatey which is Windows' equivalent of apt-get tool on Linux.

To get Chocolatey, just run this command in your Powershell console (in Administrative mode):
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
And then install SuperBenchmarker in the command line shell:
c:\> cinst SuperBenchmarker
And now you are ready to load test:
c:\> sb -u http://google.com
Note: if you are using Visual Studio's command line shell, you cannot use ampersand character (&) and you have to escape it using hat (^).

Using SuperBenchmarker

Normally you would define total number of requests and concurrency:
c:\> sb -u http://google.com -c 10 -n 2000
Statement above runs 2000 requests with concurrency of 10. At the end, you are shown important metrics of the test:
Status 503:    1768
Status 200:    232

TPS: 98 (requests/second)
Max: 11271.1890515802ms
Min: 3.15724613377097ms
Avg: 497.181240820346ms

50% below 34.0499543844287ms
60% below 41.8178295863705ms
70% below 48.7612961478952ms
80% below 87.4385213898198ms
90% below 490.947293319644ms
So the breakdown of the statuses returned, TPS (transaction per second), minimum, maximum and average of the time taken. But more importantly, your percentiles that really should be driving your performance SLAs (90% or 99%). [Never use the average for anything].

In case you need to dig deeper, a log file gets created in the current directory with the name run.log which you can change using -l parameter:
c:\> sb -u http://google.com -c 10 -n 2000 -l c:\temp\mylog.txt
log file is a tab separated file which contains these columns: order number (based on the time started not the time ended), status code, time taken in ms and then any custom parameters that you might have had - see below.

Sometimes when running a test for the first time, something might not have been quite right in which case you can make a dry run/debug using -d parameter that makes a single request and the body of the response will be shown at the end. If you want to see the headers as well, use -h parameter.
c:\> sb -u http://google.com -c 10 -n 2000 -d -h

Supplying request headers or a payload for POST, PUT and DELETE

In order to pass your tailored request headers, a template file needs to be defined which is basically the HTTP request template (minus the first line defining verb and URL and version):
c:\> sb -u http://google.com -t template.txt
And the template.txt contains our custom headers (from the second line of the HTTP request):
User-Agent: SuperBenchmarker
MyCustomHeader: foo-bar;baz=biz
Please note that you don't have to provide headers such as Host and Content-Length - in fact it will raise errors. These headers will be automatically added by the underlying framework.

For using POST, PUT and DELETE we need to supply the verb parameter:
c:\> sb -u http://google.com -v POST
But this request would require a payload as well which we need to supply. We use the template file to supply HTTP payload as well as any headers. Similar to an HTTP request, there must be an empty line between headers and body:
User-Agent: WhateverValueIWant
Content-Type: x-www-formurlencoded

name=value&age=25

Parameterising your requests

Basically you can parameterise your requests using a CSV file containing values, your plugin DLL or by specifying randomisation.

You would define parameters in URL and headers (payload not yet supported but coming soon in 0.5) using SuperBenchmarker's syntax:
{{{MyParameter}}}
As you can see, we use three curly brackets to denote a parameter. For example the statement below defines a customerId parameter:
c:\> sb -u "http://myserver.com/api/customer?customerid={{{customerId}}}^&ignore=false"
Please note quoting the URL and use of ^ to escape & character - if you are using Visual Studio command prompt. To run the test successfully, you need to provide a CSV file containing customerId:
customerId
123,
245,
and use -f option to run the test:
c:\> sb -u "http://myserver.com/api/customer?customerid={{{customerId}}}&ignore=false" -f c:\mypath\values.csv
Alternatively, you can use a plugin DLL to provide values:
c:\> sb -u "http://myserver.com/api/customer?customerid={{{customerId}}}&ignore=false" -p c:\mypath\myplugin.dll
This DLL must have a single public class implementing IValueProvider interface which has a single method:
public interface IValueProvider
{
    IDictionary<string, object> GetValues(int index);
}
For every request implementation of the interface is called and the index of the request is passed to and in return a dictionary of field names with their respective values is passed back.

Now we have a new feature that in most cases alleviates the need for CSV file or plugin and that is the ability to setup random value provider in the definition of the parameter itself:
c:\> sb -u "http://myserver.com/api/customer?customerid={{{customerId:RAND_INTEGER:[1000:2000]}}}&ignore=false"
The parameter above is set up to be filled by a random integer between 1000 and 2000.
Possible value types are:
  • String: using RAND_STRING. Will output random words
  • Date: using RAND_DATE (accepts range)
  • DateTime: using RAND_DATETIME (accepts range)
  • DateTimeOffset: using RAND_DATETIMEOFFSET which outputs ISO dates (accepts range)
  • Double: using RAND_DOUBLE (accepts range)
  • Name: using RAND_NAME. Will output random names

Feedback

Don't forget to feedback with issues and feature requests in the GitHub page. Happy load testing!

Thursday, 9 May 2013

Performance series - Announcing SuperBenchmarker sb.exe for generating load on your API/Site

[Level T1] Some of you might be doing performance analysis for living, and if so, you have access to expensive performance tools. But for those who are not and get drawn into investigating performance of their own application or their peers, there is really not a great free tool that you can just point to a URL and hammer.

Well, actually there is: Apache benchmark or ab.exe which has served the community since almost 20 years ago. It is free and very performant, i.e. does not require a lot of resources to run so does not affect the performance even if you benchmark your localhost server. But it has limitations (only GET, no HTTPS, no parameterisation) and I could not find a tool so I ended up writing one for my own use. And now I am sharing it.



SuperBenchmarker or sb.exe is a single-exe (ilmerged with dependencies inside) application that can be used to call various endpoints. It can do GET as well as other verbs, can do request templating and you can provide values for placeholders in URL or your template. It also can output a lot of tracing info in case you need it.

It requires .NET 4.5 but you can target any site or API written in Ruby, PHP, Java, ect. You can download it from here if you do not want to use NuGet. [Update: It has been reported that some people have had issue running on x64 windows. If so please comment on this GitHub issue]

So version 0.1 is out and it works although project needs some love with tests and a few features. There are also some shortcuts taken which needs to be sorted out - but it works.You can clone the code and build it (running build.ps1) or simply use NuGet to download it. [Update: preferred method is using Chocolatey - see below]

PM> Install-Package SuperBenchmarker

For usage, see the wiki on the GitHub. I value feedbacks, also if interested to get involved with the project let me know.



Update

Courtesy of Mike Chaliy, this has now a chocolatey package. So if you have chocolatey installed (and if not here are the instructions), simply run this command in command line:

cinst SuperBenchmarker

Info

Usage:
sb.exe -u url [-c concurrency] [-n numberOfRequests] [-m method] [-t template] [-p plugin] [-f file] [-d] [-v] [-k] [-x] [-q] [-h] [-?]
Parameters:
-u Required. Target URL to call. Can include placeholders.
-c Optional. Number of concurrent requests (default=1)
-n Optional. Total number of requests (default=100)
-m Optional. HTTP Method to use (default=GET)
-p Optional. Name of the plugin (DLL) to replace placeholders. Should contain one class which implements IValueProvider. Must reside in the same folder.
-f Optional. Path to CSV file providing replacement values for the test
-d Optional. Runs a single dry run request to make sure all is good (boolean switch)
-v Optional. Provides verbose tracing information (boolean switch)
-k Optional. Outputs cookies (boolean switch)
-x Optional. Whether to use default browser proxy. Useful for seeing request/response in Fiddler. (boolean switch)
-q Optional. In a dry-run (debug) mode shows only the request. (boolean switch)
-h Optional. Displays headers for request and response. (boolean switch)
-? Optional. Displays this help. (boolean switch)


Examples:

-u http://google.com
-u http://google.com -n 1000 -c 10
-u http://google.com -n 1000 -c 10 -d (runs only once)
-u http://localhost/api/myApi/ -t template text (file contains headers to be sent for GET. format is same as HTTP request)
-u http://localhost/api/myApi/ -m POST -t template.txt (file contains headers to be sent for POST. format is same as HTTP request with double CRLF separating headers and payload)
-u http://localhost/api/myApi/{{{ID}}} -f values.txt (values file is CSV and has a column for ID)-u http://localhost/api/myApi/{{{ID}}} -p myplugin.dll (has a public class implementing IValueProvider defined in this exe)
-u http://google.com -h (shows headers)
-u http://google.com -h -q (shows cookies)
-u http://google.com -v (shows some verbose information including URL to target - especially useful if parameterised)

Monday, 1 April 2013

Monitor your ASP.NET Web API application using your own custom counters

[Level T2] OK, so you have created your Web API project and deployed into production and now boss says dude, we have performance problems. Or maybe head of testing wants to benchmark the application and monitor it over the course of next releases so we catch problems early. Or you are just a responsible geek interested in the performance of your code.

NOTE: THIS BLOG POST REFERS TO AN EARLIER VERSION OF PERFIT. PLEASE VISIT https://github.com/aliostad/PerfIt FOR UP-TO-DATE DOCUMENTATION

In any case, no serious web code can be written without having performance in mind. Problem is that existing system, .NET and ASP.NET performance counters can go as far as telling you overall picture of the performance and the metrics usually coalesced into a single value while you need to drill down to individual APIs and see what's happening. Now this can be another burden on your already squeezed time remaining. So how easy is it to publish counters for your individual API? Just these few steps! TLDR; :

  1. Use NuGet to install PerfIt! into your ASP.NET Web API project (make sure you get version +0.1.2 - there was a bug fixed in this version)
  2. Add PerfitDelegatingHandler to the list of your MessageHandlers
  3. Decorate those actions you want to monitor
  4. Use "Add New Item" to add an Installer class into your Web API project. Write just a single line of code for Install and Uninstall.
  5. Use InstallUtil.exe in an administrative command window to install (or uninstall) your counters. Done! 

Seeing performance counters of your own project is kinda cool!

1-Adding PerfIt! to your project

So to add PerfIt! to the project, simply use NuGet console:
PM> Install-Package PerfIt


2-Adding PerfItDelegatingHandler 

Now we need to add the delegating handler:

config.MessageHandlers.Add(new 
      PerfItDelegatingHandler(config, "My test app"));

The string passed in here is the application name. This will be used as the instance name in the performance counter. You can see that in the screenshot above.

3-Decorate actions

For any action that you want the counters to be published, use PerfIt action filter and define the counters you want to see published:

// GET api/values
[PerfItFilter(Description = "Gets all items",
   Counters = new []{CounterTypes.TotalNoOfOperations,
   CounterTypes.AverageTimeTaken})]
public IEnumerable<string> GetAll()
{
    Thread.Sleep(_random.Next(50,300));
    return new string[] { "value1", "value2" };
}

// GET api/values/5
[PerfItFilter(Description = "Gets item by id", 
   Counters = new[] { CounterTypes.TotalNoOfOperations, 
   CounterTypes.AverageTimeTaken })]
public string Get(int id)
{
    Thread.Sleep(_random.Next(50, 300));
    return "value";
}

Here we have decorated GetAll and Get to publish two types of counters (currently these counters are available but more will be added - see below).

The format of the counter will be [controller].[action].[counterType] (see screenshot above). As such, please note that we had to change the first Get to GetAll to so that the counter names do not get mixed up. If you cannot do that (while ASP.NET Web API allows you do change the name as long as the action starts with the verb), alternatively use the Name property of the filter to define your own custom name (which we did not specify here to allow default naming take place).

Description property will appear in the perfmon.exe window and is known as CounterHelp. Counters is an array of string, each string being a defined against PerfIt! runtime (see roadmap for more info) as a counter type. Another option is the ability to define Category for the counter which we also did not specify so by default, it will be the assembly name. You can see the category in the screenshot above as PerfCounterWeb (see the typo!).

4-Adding Installer to your project 

Now use "Add New Item" to add an installer class to your project. You might have not seen this in the new item templates but it is definitely there (screenshot from VS2012 but project is .NET 4.0 so can be done in VS2010):


After adding the class, override Install and Uninstall methods and add the code below (hit F7 to see the code):

public override void Install(IDictionary stateSaver)
{
    base.Install(stateSaver);
    PerfItRuntime.Install();
}

public override void Uninstall(IDictionary savedState)
{
    base.Uninstall(savedState);
    PerfItRuntime.Uninstall();
}

5-Use installutil.exe to install counters

Just make sure you open an administrative command window. Use Visual Studio command prompt since it has the right path for InstallUtil.exe. cd to your bin folder and register your assembly:
c:\projects\myproject\bin>InstallUtil.exe -i MyWebApplication.dll
This should do the trick. Use -u switch to uninstall the counters.

That is all that is needed. Just hit your app and start benchmarking your app in the perfmon.exe.

Turning off the publishing of counters

In normal/production circumstances, you might wanna turn off publishing of the performance counters. In this case, you can put the line below in the appSettings of your web.config:

<appSettings>
    <add key="perfit:publishCounters" value="false"/>

I have kept the default behaviour to publish counters - so to eliminate one configuration step to get up and running. This may change in the future - but unlikely.

PerfIt! Roadmap

I needed to add performance counters to my Web API application. With wife away and a few Easter bank holiday days, I managed to start and finish version 0.1 of PerfIt! library.

Future work includes adding more counter types and looking at improving the pipeline. PerfIt! has been built on the top of its own extensibility framework so very easy to add your own counters, all you need is to implement CounterHandlerBase and then register the handler in PerfItRuntime.HandlerFactories.

Any problems, issues, comments or feedbacks, please use the GitHub issues to get it touch. Enjoy!

Thursday, 21 March 2013

Performance series - Memory leak investigation Part 1

[Level T2] If you have worked a few years within the industry, it is very unlikely that you have not encountered a case of memory leak. Whether your own code or someone else's, it is an annoying problem to diagnose and fix. The problem's scale and the effort to fix it increases exponentially with the scale and complexity of the application and deployment.

Many companies use application benchmarking and performance testing to find these problems early on. But as I experienced myself, problems found earlier as part of performance testing are not necessarily easier to solve. Lengthy cycle of gathering metrics, analysis, coming up with one or more hypothesis/es and then fixing and trying and testing it could be very time consuming and jeopardising delivery and meeting deadlines.

In these cases, focusing on what is important and what is not saves the day. A common problem in troubleshooting performance bugs is information overload and the existence of red herrings that confuse the picture. There is a myriad of performance counters that you could spend hours and days explaining their anomalies that have nothing to do with the problem you are trying to solve. Having worked as a medical doctor before, I have seen this in the field of medicine many many times. Human's body as a very big application - eternally more complex that any given application - demonstrates similar behaviour and I have learnt to be focused on identifying and fixing the problem at hand rather than explaining each and every oddity.

As such, I am starting this series with an overview of the performance counters and tools to be used. There are many posts and even books on this very topic. I am not claiming that this series is a comprehensive and all-you-need guide. I am actually not claiming anything. I am simply sharing my experience and hope it will make your troubleshooting journey less painful and help you find the culprit sooner.

A few notes on the platform

This is exclusively a Windows and mainly a .NET series - although part of this series could help with none .NET applications. Also focus is mainly on ASP.NET web applications as the impact of even a small memory leak can be very big but the same guidelines can be equally applied to desktop applications.

What is a memory leak?

Memory leak is usually considered as the memory which is allocated by the application and becomes inaccessible - as such cannot be deallocated. But I do not like this definition. For example this code does not qualify for memory leak but it will lead to out of memory:

var list = new List<byte[]>();
for(i=0; i< 1000000; i++)
{
   list.Add(new byte[500 * 1024]); // 500 KB
}

As can be seen, data is accessible to the application but application does not unload the allocated memory and keeps piling up memory allocation in heap.

For me, memory leak is a constant/stepwise allocation of memory without deallocation which usually leads to OutOfMemoryException. The reason I say usually is because small leaks can be tolerated as many desktop applications are closed at the end of the day and many website daily recycle their app pools. However, they are still leaks and you have to fix them when you get the time since with change in conditions, leaks that you could tolerate can bring down your site/application.

Process memory/time in 4 different scenarios

In the top right diagram, we see constant allocation but it coincides with deallocation of memory - as such not a leak. This scenario is common in ASP.NET Caching (HttpRuntime.Cache) where 50% of the cache is purged when memory used reaches a certain threshold.

In the bottom right diagram, de-allocation does not happen or its rate is the same as the allocation when the memory size of the application's process reaches a threshold. This pattern can be seen with the SQL Server where it uses as much memory as it can until it reaches a threshold.

How do I establish a memory leak?

All you have to do is to ascertain your application meets the criteria described above. Just observe the memory usage over time under load. It is possible that the leak happens only in a certain condition or when using a particular functionality of the app so you have to be careful about that.

What tool do you need to do that? Even using a Task Manager could be good enough to start with.

Tools to use 

Normally you would start with Task Manager. Just a quick look at the Task Manager or eye-balling the memory size of the process when the app is running and under load is a simple but effective start.

The mainstay of the memory leak analysis is Windows Performance Monitor, aka Perfmon. This is very important in establishing a benchmark, monitoring changes over new version releases and identifying problems. In this post I will look into some essential performance counters.

If you are investigating a serious or live memory leak, you have to have a .NET Memory Profiler. Currently 3 different profilers exist:

  1. RedGate's ANTS Profiler
  2. Jetbrain's dotTrace
  3. Scitech's Memory Profiler

Each tool has its own pros and cons. I have experience with SciTech's and I must say I am really impressed by it.

The most advanced tool is Windbg which is a really useful tool but has a steep learning curve. I will look at using it for memory leak analysis in future posts.

Initial analysis of the memory leak

Let's look at a simple memory leak (you can find the snippets here on GitHub):

var list = new List<byte[]>();
for (int i = 0; i < 1000; i++)
{
    list.Add(new byte[1 * 1000 * 1000]);
    Thread.Sleep(200);
}

Process\Private Bytes performance counter is a popular measure of total memory consumption. Let's look at this counter in this app:


So how do we find out if it is a managed or unmanaged leak? We use .NET CLR Memory\#Bytes in all heaps counter:


As can be seen above, white private bytes increases constantly, heap allocation happens in steps. This stepwise increase of heap is consistent with a managed memory leak. In contrast let's look at this unmanaged leak code:

var list = new List<IntPtr>();
for (int i = 0; i < 400; i++)
{
    list.Add(Marshal.AllocHGlobal(1*1000*1000));
    Thread.Sleep(200);
}
list.ForEach(Marshal.FreeHGlobal);

And here is flat bytes in heap:


So this case is an unmanaged memory leak.

In the next post I will look at a few more performance counter and GC issues.

Saturday, 2 February 2013

Performance series: GUIDs vs. IDENTITY INT in RDBMS

[Level C2] We have been discussing with a few colleagues about whether we should adopt GUIDs as our primary keys. At the same time, we had a meeting with our DBAs to discuss other scenarios and the topic came up.

When the systems become more complex and you have more layers between your user interface and database, not knowing the ID of the aggregate root before storing can pose unnecessary challenges. On the other hand, the cost of choosing GUID as the primary key of the database is usually unknown. That is why I set out to find out the exact cost of choosing GUID instead of IDENTITY INT as the primary key of the table.

Pros and cons

This is not a new topic. There are quite a few resources that discuss this topic and list the pros and cons. Jeff Atwood's blog post from 6 years ago is a short and sweet one explaining why StackOveflow decided to move the IDs (at least some of them) to GUID. It also contains many references to other related posts that discuss the topic - all of which are good reads especially this one.

Why GUID?

For me, the main reason to choose a GUID is to know the ID of the entity even before persisting. If you do not have this requirement, you might still want to use GUID and avoid IDENTITY INT especially if you are using sharding or master-master replication. But for me, the first one is vital. Why?

If you use CQRS and commands to store your entities, you would naturally implement commands as an asynchronous operation. Your UI would have to find out about the result of the operation by polling or subscribing to the event published after processing the command. If you do not know the ID of your entity before persistence, you would end up using a different ID as a reference.

Problem with GUIDs

Apart from GUIDs being unreadable, there are performance implications for using GUIDs. The main ones are:

  1. GUID is a 16-byte type while INT is a 4-byte type. With storage nowadays very cheap, this normally is not a problem from the storage point of view. The problem is that reads (and writes) will be multiplied by 4x.
  2. The most serious problem is when you use the GUID ID as the clustered index of the table. In this case, with every INSERT you would be changing the layout of the data potentially having to move many data pages. This is unlike IDENTITY INT clustered indexes where data is stored sequentially providing the best performance.

Benchmarks

This old article provides a benchmark of the cost of the writes. Considering very little has been changed with the basic functionality of the SQL Server, this benchmark is still relevant - if not accurate. According to the results, cost of writing GUID primary keys in a database containing 1,000,000 records is 10x the cost of writing INT primary keys. This cost goes up exponentially when the table contains more rows.

One of the solutions presented in the article is to have a semi-sequential GUID generated in the database. In fact since SQL Server 2005, there is an option to do that using NEWSEQUENTIALID(). This will change the overhead to a mere linear 10% on both reads and writes.

The problem with these solutions is that the GUID is still generated in database so does not solve the problem of knowing the ID before storing the entity.

My solution and benchmark

As discussed, the problem generally is to do with the non-sequential nature of the GUIDs. But who said we should use the primary key as the clustered index?!

Basically my solution is to:

  1. Add an IDENTITY INT column (I called it order Id - nothing to do with customer orders) and set it to be the clustered index. If you do not want to use an additional column, you could use a DATETIME column to store a timestamp which is usually very useful
  2. Add a UNIQUEIDENTIFIER column (GUID data type in SQL Server) as the main ID. Set that to be the primary key.
  3. Add a non-clustered index for the GUID ID

This will keep the data storage sequential while benefiting from system generated IDs instead of database generated IDs. There are two drawbacks: 1) storing an additional column 2) having an additional non-clustered index which takes some space and makes reads and writes slightly slower. Bear in mind, this is  recommended only if you keep the table only for transactional usage and to store and retrieve by key and not for reporting. In most cases, this is what you would normally do especially if you are implementing CQS or CQRS.

* Using an IDENTITY INT as the clustered index

As can be seen, using this technique, performance of the GUID primary key is close to the performance of the INT primary key (roughly 10% overhead).

Conclusion

Performance of a GUID primary key is acceptable and adds mere a 10% overhead, if we use another INT or DATETIME timestamp as the clustered index.


Sunday, 6 May 2012

Performance comparison of object instantiation methods in .NET

In the previous post, I compared performance of various methods of code invocation that are in our arsenal in .NET framework.

Last night I was reviewing ASP.NET Web API Source Code that I noticed this snippet:
private static Func<object> NewTypeInstance(Type type)
{
    return  Expression.Lambda<Func<object>>(Expression.New(type)).Compile();
}

But surely, compiling a lambda expression is really costly (as we have seen in the last post), why shouldn't we use simply do this (if we are suppose to just return a Func):
private static Func<object> NewTypeInstance(Type type)
{
    var localType = type; // create a local copy to prevent adverse effects of closure
 Func<object> func = (() => Activator.CreateInstance(localType)); // curry the localType
    return func;
}

Well, I asked this very question from Henrik F Nielsen, ASP.NET Web API team's architect. And he was very helpful getting back to me quickly that "compiling an expression is the fastest way to create an instance. Activator.CreateInstance is very slow".

OK, I did not know that, but it seems to be a good topic for a blog post! So here we are where I compare these few scenarios:

  1. Direct use of the constructor
  2. Using Activator.CreateInstance
  3. Using a previously bound reflected ConstructorInfo (see previous post for more info)
  4. Compiling a lambda expression every time and running it
  5. Caching a compiled lambda expression and running it (what ASP.NET Web API does)

Test and code

In this one, I could get a bit more imaginative with my code since in the last post I already established overhead/merits of various code invocation methods. For the object to construct, I use a simple class which has a default parameterless constructor. Results will be different using a parameterful constructor but I think parameterless constructor is a more pure case.

So I have created a few Action extension methods to perform the tedious repeated snippets in the last post. Each method runs 1,000,000 times which is not high enough but as we will see (and have seen in the last post), compiling a lambda expression every time is really slow so 10 million would be very high.
public class ConstructorComparison
{
 static void Main()
 {
  const int TotalCount = 1000 * 1000; // 1 million
  Stopwatch stopwatch = new Stopwatch();
  Type type = typeof(ConstructorComparison);
  var constructorInfo = type.GetConstructors()[0];
  var compiled = Expression.Lambda<Func<object>>(Expression.New(type)).Compile();

  Action usingConstructor = 
    () => new ConstructorComparison();
  Action usingActivator = 
    () => Activator.CreateInstance(type);
  Action usingReflection = 
    () => constructorInfo.Invoke(new object[0]);
  Action usingExpressionCompilingEverytime =
   () => Expression.Lambda<Func<object>>(Expression.New(type))
    .Compile();
  Action usingCachedCompiledExpression = 
    () => compiled();
  Action<string> performanceOutput = 
    (message) => Console.WriteLine(message);

  Thread.Sleep(1000);
  Console.WriteLine("Warming up ....");
  Thread.Sleep(1000);

  Console.WriteLine("Constructor");
  usingConstructor
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.WriteLine("Activator");
  usingActivator
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.WriteLine("Reflection");
  usingReflection
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.WriteLine("Compiling expression everytime");
  usingExpressionCompilingEverytime
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.WriteLine("Using cached compiled expression");
  usingCachedCompiledExpression
   .Repeat(TotalCount)
   .OutputPerformance(stopwatch, performanceOutput)();

  Console.Read();
 }
}

public static class ActionExtensions
{
 public static Action Wrap(this Action action, Action pre, Action post)
 {
  return () =>
       {
           pre();
           action();
           post();
       };
 }

 public static Action OutputPerformance(this Action action, Stopwatch stopwatch, Action<string> output)
 {
  return action.Wrap(
   () => stopwatch.Start(),
   () => 
    {
     stopwatch.Stop();
     output(stopwatch.Elapsed.ToString());
     stopwatch.Reset();
    }
   );
 }

 public static Action Repeat(this Action action, int times)
 {
  return () =>  Enumerable.Range(1, times).ToList()
   .ForEach(x => action());
 }
}

Results and conclusion

Here is output from the program:

Warming up ....
Constructor
00:00:00.0815479
Activator
00:00:00.1732489
Reflection
00:00:00.4263699
Compiling expression everytime
00:02:11.5762143
Using cached compiled expression
00:00:00.0855387

So as we can see:

  • Using a cached compiled expression is almost as fast as the constructor 
  • Using Activator is x2 slower
  • Using reflection is x5 slower
  • Compiling a lambda expression every time is really slow: in this case + x1000 times slower 
So indeed as Henrik said, having only the type of the class, using a cached compiled expression is the fastest method.

Saturday, 5 May 2012

Performance comparison of code invocation methods in .NET


Introduction

.NET has moved to become more of a functional programming since .NET 3.0. Currently there are many ways that you can invoke execution of code such as direct call, reflection, delegates, compiled expressions, dynamic, etc. In this post I will compare performance of these methods. Part of the inspiration for this comparison was reviewing the ASP.NET Web API code.

Readability/maintainability vs. Performance

Functional programming is on the rising popularity. Why now, is it not decades old? 

Part of the popularity goes back to the fact that now we run much faster machines - with more cores. And we need to solve more complex problems and there is a need to write more readable code and be able to expression the code more succinctly. On the top of all this, add the fact that we need to invoke code in parallel to get the best of our machines horse power. 

We are writing code that compared to 20 years ago is quite inefficient, using more processor cycles. C was slower than Assembly, and C# slower than C but it certainly does not make sense to write in Assembly. But language is only part of the story. We get choices in one language itself. In .NET, we sometimes use IEnumerable<T>.Count() instead of using IList<T>.Count. While .NET in case of .Count() first tries to convert the IEnumerable<T> to ICollection<T> and if it does not succeed then loops through to get the count, in other cases framework cannot improve the performance. 

Our code is commonly a compromise between readability and performance. I for one would pick former over latter but my decision needs to be an informed decision. If a code is 1000 times slower (and that part of the code is called many times) I definitely would sacrifice readability, but if it is only twice slower, I would pick readability.

Context is also important. Poor performance on server can be costly but on the client usually would not be noticed. A real-time image processing code has to squeeze every drop of performance it can (having done real-time image processing in C++, I am pretty familiar with it), while an asynchronous batch process could use a more liberal approach. In any case, micro-optimisation is a common pitfall that I try not to fall into.

Code Invocation

In .NET we can use different ways to invoke some code (colour coded based on category):
  1. Static method call
  2. Instance method call
  3. Instance method call on virtual methods where CLR has to walk up/down the inheritance hierarchy to understand the piece of code to run.
  4. Invocation using reflection
  5. Invocation using a previously bound reflected object
  6. Invoking a delegate
  7. Invoking a Func or a compiled expression (which itself is a delegate)
  8. DynamicInvoke on a delegate
  9. Compiling a lambda expression and executing it
  10. Invocation on a dynamic object
For our test, I am using a simple class which calculates tangent of an angle. I have done all I could to make sure condition for all these scenarios are similar so that the difference in performance is only related to the call method.
internal class WidgetBase
{
 public virtual double VirtualGetTangent(double value)
 {
  throw new NotSupportedException();
 }
}

internal class Widget : WidgetBase
{

 public override double VirtualGetTangent(double value)
 {
  return Math.Sin(value) / (Math.Cos(value) + 0.0000001f);
 }

 public virtual double InstanceGetTangent(double value)
 {
  return Math.Sin(value) / (Math.Cos(value) + 0.0000001f);
 }

 public static double GetTangent(double value)
 {
  return Math.Sin(value) / (Math.Cos(value) + 0.0000001f);
 }

}

Now let's see how each scenario is implemented (I have commonly ignored the return value).
static void CallStatic(double value)
{
 Widget.GetTangent(value);
}

static void CallInstance(double value, Widget widget)
{
    widget.InstanceGetTangent(value);
}

static void CallVirtualInstance(double value, Widget widget)
{
 widget.VirtualGetTangent(value);
}

First three call types need not much explanation. Static method and instance method do not have much difference. Internally in CLR, instance method has an additional parameter for the instance itself passing this to it. Jeff Richter explains the difference between IL's call and callvirt where callvirt is slower than call but as we will see difference is minimal.
static void CallReflector(double value, Widget widget)
{
    MethodInfo methodInfo = typeof(Widget).GetMethods(BindingFlags.Instance |
  BindingFlags.Public).Where(x => x.Name == "InstanceGetTangent").First();
    methodInfo.Invoke(widget, new object[] { value });
}

static void CallMethodInfo(double value, MethodInfo methodInfo, Widget widget)
{
    methodInfo.Invoke(widget, new object[] { value });
}
With reflection, we have two steps. First one is binding where we get the MethodInfo from the type object. Next one is the actual execution where we use Invoke to execute the method. As you can see, second method is passed the MethodInfo while the first one binds every time. In our example, this will incur the overhead of boxing since both our input and output are double while parameters passed in and out of Invoke is object. However, I have decided to keep it so since this could also happen in a real scenario.

public delegate double CalculateIt(double value);

static void CallDelegate(double value, CalculateIt d)
{
 d(value);
}

static void CallFunc(double value, Func<double, double> func)
{
 func(value);
}

static void CallDelegateDynamicInvoke(double value, Delegate d)
{
 d.DynamicInvoke(new object[] { value });
}

static void CallExpression(double value, Expression<Func<double, double>> expression)
{
    Func<double , double> compile = expression.Compile(); 
    compile(value);
}
CalculateIt is a delegate defined above and called in the first method. Difference between first call and third is that the first one is a strongly typed delegated while the third one is simply weakly typed delegate that can be only called using DynamicInvoke.
static void CallDynamic(double value, Widget widget)
{
    dynamic d = widget;
    d.InstanceGetTangent(value);
}
Dynamic object call is simple and uncomplicated as can be seen above.

NOTE: Metrics of running a compiled expression is the same as that of Func so it is not separately calculated. My point here is to show that compiling an expression all the time is expensive and I have seen cases were people do it - if you have not seen. I particularly saw an example where it was used for Null Guard expressions.

Test execution

Each method was called 10,000,000 times and results where compared. I have used a code which is very verbose but I was trying to eliminate anything that could skew the results.

There are other factors such as garbage collection and other processes running on the machine but I have ran the code quite a few times and results were more or less consistent with only 1-2% variation.


Results review

As it can be seen, compiling an expression is 10 times slower than most other call types including Func<T> delegates (result of expression compilation). This is particularly important since some of the new frameworks (e.g. ASP.NET Web API) heavily use expression compilation.
Also of importance is that binding is significant overhead in reflection. By binding once and invoking many times we can improve the performance.

Another important insight is that dynamic, unlike what it is famous for, is not that much slower than strongly typed direct calls (less than twice).

Conclusion

Compiling a lambda expression and running it is the slowest type of code invocation. There is not a meaningful difference between calling a static, instance, virtual method or Func/delegate. Calling a method on a dynamic object less than twice slower than making a direct call.

Source code

As I said, my code is very verbose to eliminate any element that could skew the result. In case you need to review, modify or run the source code, I have brought the source code here:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Text;
using System.Threading;

namespace PerformanceComparison
{

 class Program
 {
  private static Random _random = new Random();
  public delegate double CalculateIt(double value);

  static void Main(string[] args)
  {

   const int TotalCount = 10000 * 1000; // 10 million
   Stopwatch stopwatch = new Stopwatch();
   Expression<Func<double, double>> expression = 
    (double value) => Math.Sin(value) / (Math.Cos(value) + 0.0000001f);
   Func<double, double> func = expression.Compile();
   Widget widget = new Widget();

   Thread.Sleep(2000);

   // ________   Static ____________________________________________________
   Console.WriteLine("Static ---------------------------------------");
   stopwatch.Start();
   for (int i = 0; i < TotalCount; i++)
   {
    CallStatic(_random.NextDouble());
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Instance ____________________________________________________
   Console.WriteLine("Instance ---------------------------------------");
   stopwatch.Start();
   for (int i = 0; i < TotalCount; i++)
   {
    CallInstance(_random.NextDouble(), widget);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Instance Virtual _______________________________________________
   Console.WriteLine("Instance Virtual --------------------------------");
   stopwatch.Start();
   for (int i = 0; i < TotalCount; i++)
   {
    CallVirtualInstance(_random.NextDouble(), widget);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Reflected ____________________________________________________
   Console.WriteLine("Reflected ---------------------------------------");
   stopwatch.Start();
   for (int i = 0; i < TotalCount; i++)
   {
    CallReflector(_random.NextDouble(), widget);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Reflected after binding ___________________________________________________
   Console.WriteLine("Reflected after binding ------------------------------");
   MethodInfo methodInfoInstance = typeof(Widget).GetMethod("InstanceGetTangent",
    BindingFlags.Instance | BindingFlags.Public);
   stopwatch.Start();
   for (int i = 0; i < TotalCount; i++)
   {
    CallMethodInfo(_random.NextDouble(), methodInfoInstance, widget);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Delegate ____________________________________________________
   Console.WriteLine("Delegate -------------------------------------------------");
   stopwatch.Start();
   CalculateIt c = widget.InstanceGetTangent;
   for (int i = 0; i < TotalCount; i++)
   {
    CallDelegate(_random.NextDouble(), c);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Func ____________________________________________________
   Console.WriteLine("Func -------------------------------------------------");
   stopwatch.Start();
   for (int i = 0; i < TotalCount; i++)
   {
    CallFunc(_random.NextDouble(), func);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Delegate (Dynamic Invoke) ____________________________________________________
   Console.WriteLine("Delegate DynamicInvoke ------------------------------------------");
   stopwatch.Start();
   for (int i = 0; i < TotalCount; i++)
   {
    CallDelegateDynamicInvoke(_random.NextDouble(), func);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Expression ____________________________________________________
   Console.WriteLine("Expression -------------------------------------------------");
   stopwatch.Start();
   for (int i = 0; i < TotalCount / 100; i++)
   {
    CallExpression(_random.NextDouble(), expression);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   // ________   Dynamic ____________________________________________________
   Console.WriteLine("Dynamic -------------------------------------------------");
   stopwatch.Start();
   for (int i = 0; i < TotalCount; i++)
   {
    CallDynamic(_random.NextDouble(), widget);
   }
   stopwatch.Stop();
   Console.WriteLine(stopwatch.Elapsed.ToString());
   stopwatch.Reset();

   Console.Read();
  }

  static void CallStatic(double value)
  {
   Widget.GetTangent(value);
  }

  static void CallInstance(double value, Widget widget)
  {
   widget.InstanceGetTangent(value);
  }

  static void CallVirtualInstance(double value, Widget widget)
  {
   widget.VirtualGetTangent(value);
  }


  static void CallReflector(double value, Widget widget)
  {
   MethodInfo methodInfo = typeof(Widget).GetMethod("InstanceGetTangent",
    BindingFlags.Instance | BindingFlags.Public);
   methodInfo.Invoke(widget, new object[] { value });
  }

  static void CallMethodInfo(double value, MethodInfo methodInfo, Widget widget)
  {
   methodInfo.Invoke(widget, new object[] { value });
  }

  static void CallDelegate(double value, CalculateIt d)
  {
   d(value);
  }

  static void CallFunc(double value, Func<double, double> func)
  {
   func(value);
  }

  static void CallDelegateDynamicInvoke(double value, Delegate d)
  {
   d.DynamicInvoke(new object[] { value });
  }

  static void CallExpression(double value, Expression<Func<double, double>> expression)
  {
   Func<double, double> compile = expression.Compile();
   compile(value);
  }




  static void CallDynamic(double value, Widget widget)
  {
   dynamic d = widget;
   d.InstanceGetTangent(value);
  }



 }

 internal class WidgetBase
 {
  public virtual double VirtualGetTangent(double value)
  {
   throw new NotSupportedException();
  }
 }

 internal class Widget : WidgetBase
 {

  public override double VirtualGetTangent(double value)
  {
   return Math.Sin(value) / (Math.Cos(value) + 0.0000001f);
  }

  public virtual double InstanceGetTangent(double value)
  {
   return Math.Sin(value) / (Math.Cos(value) + 0.0000001f);
  }

  public static double GetTangent(double value)
  {
   return Math.Sin(value) / (Math.Cos(value) + 0.0000001f);
  }

 }

}