Understanding ASP.NET Performance for Reading Incoming Data

Matt Watson Insights for Dev Managers Leave a Comment

Receiving incoming data in an ASP.NET application is a common task that most apps do. There are lots of ways of receiving data. Developers commonly write apps to handle HTML forms, file uploads, and APIs. There are a lot different types of APIs and they can receive data in JSON, XML, or other formats via ASP.NET Web API, MVC, WCF, etc.

So this got me thinking… how do you track the performance of reading and sending data, and how does the performance compare across all of the different frameworks?

This article helps explain how ASP.NET receives data and some basics about how performance compares.

 

Understanding the basics of incoming data

Let’s pretend you have a simple WEB API controller and all it does is handle a list of users being uploaded to it in JSON. What does ASP.NET actually do under the hood?

ASP.NET has to do 3 things:

  1. Actually read the incoming bytes that were sent via a POST
  2. Deserialize those bytes as JSON
  3. Map the resulting JSON to your actual .NET class types

For this example, here is the basic WEB API code we are testing. The json is being uploaded from a simple console application. The data being uploaded is 10,000 users which equates to about 1.3MB of data.

prefix read data code

Using Stackify’s free ASP.NET profling tool, Prefix, we can see just how long it takes to read the incoming data. It shows a total of 90ms to fully read in the data.

prefix read data example

When you are trying to optimize the performance of your application, it is important to understand how something as simple as reading data can impact performance.

Bring on the performance comparisons!

In the previous example I showed you how you can use a tool like Prefix to see how long it takes to read incoming data. Now we will use it to compare several different ways you could receive this data to see how different methodologies perform. For all of these types, I am going to be uploading the same JSON of 10,000 users. The goal is to provide some high level guidance to compare the performance.

Results from the different tests:

Framework Method Performance
WEB API Use basic API input
UploadList(List<User> users) which .NET automatically reads, parses, and binds the data to our list of User objects
90-200ms+ (very erratic)
WEB API Read incoming data manually as a string

Request.Content.ReadAsStringAsync()

15-50ms
WEB API Read manually and then deserialize to JSON with JSON.NET from a string 45-50ms
MVC Use basic API input
UploadList(List<User> users) which .NET automatically reads, parses, and binds the data to our list of User objects
1000ms!
MVC Read incoming data manually as a string

new StreamReader(Request.InputStream);

20ms
MVC Read manually and then deserialize to JSON with JSON.NET from a string 35ms
WCF Use standard WCF generated client code to make a SOAP based request 30ms
ASP.NET Core RC1 Use basic API input for controller action UploadList(List<User> users) 200ms

 

Testing results & insights

Web API is faster than MVC for JSON performance

MVC uses the built in JSON serializer which is terrible for performance. Web API uses JSON.NET which performs much better. This gives Web API a big performance advantage for large JSON payloads.

Customizing Web API and MVC JSON parsing

It is possible with Web API to change the JSON parser that it uses. Please check out this blog post for great details and examples for this: Using an alternate JSON Serializer in ASP.NET Web API

For changing the JSON library with MVC, please check out these two blog posts: ASP.NET MVC 3 – Improved JsonValueProviderFactory using Json.Net and ASP.NET MVC and Json.NET

The fastest way is a little more work…

From my testing, if you are working with potentially large JSON payloads, you could potentially improve performance by manually reading the input stream and deserializing it yourself instead of letting MVC or Web API do it for you. It only takes a couple lines of code to deserialize it manually.

read json manually

WCF is out of fashion in 2016, but it is efficient

From my testing, WCF was consistently very fast. This image from Prefix shows it took about 8ms to read the incoming data and about 18ms to parse the SOAP into the array of User objects. Making this even more impressive, the incoming data was about 2x as large because it was XML instead of JSON.

prefix read data wcf

How does your app perform?

The goal was to highlight how much performance can vary from different ways of receiving and reading JSON. Simply reading and deserializing JSON can take a lot more time when you think and is typically hidden time in various tracing, profiling, and debugging tools. Prefix is a great free tool that can help you understand the performance of this and much more.

About Matt Watson

Matt is the Founder & CEO of Stackify. He has been a developer/hacker for over 15 years and loves solving hard problems with code. While working in IT management he realized how much of his time was wasted trying to put out production fires without the right tools. He founded Stackify in 2012 to create an easy to use set of tools for developers.