Why is .NET OData Serializer so slow Why is .NET OData Serializer so slow json json

Why is .NET OData Serializer so slow


Well, the answer is not the serializer.When you add EnableQuery, you are allowing by default the different methods that OData uses Select, Count, Skip, Top, Expand. But most important is that EnableQuery is an ActionFilterAttribute which means:

Filters in ASP.NET Core allow code to be run before or after specific stages in the request processing pipeline.

Check here for more info about ActionFilters

With that said, EnableQuery overrides two methods (Before/After):

public override void OnActionExecuting(ActionExecutingContext actionExecutingContext)

and

public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)

The first one is where the query options are created and validated. This involves a lot of reflection work.The second one checks if the result is set and successful, for example if you are returning an IQueryable, here is where it gets executed. The query is materialized at this level.It first tries to retrieve the IQueryable from the returning response message. It then validates the query from uri based on the validation settings on "EnableQueryAttribute". It finally applies the query appropriately, and reset it back on the response message.

As you can see, all of this extra logic is more complex than just converting the result into a JSON output which is the final step.

I took your example:

[ApiController]    [Route("api/test")]    public class WeatherForecastController : ControllerBase    {        [Route("/get1")]        [HttpGet]        [EnableQuery(EnsureStableOrdering = false)]        public ActionResult<IEnumerable<Person>> Get1()        {            var list = new List<Person>();            for (var i = 0; i < 2500; i++)            {                list.Add(new Person());            }            return list;        }        [Route("/get2")]        [HttpGet]        public IActionResult Get2()        {            var list = new List<Person>();            for (var i = 0; i < 2500; i++)            {                list.Add(new Person());            }            var json = JsonConvert.SerializeObject(list);            return Ok(json);        }        [Route("/get3")]        [HttpGet]        public IActionResult Get3()        {            var list = new List<Person>();            for (var i = 0; i < 2500; i++)            {                list.Add(new Person());            }            return Ok(list);        }