locked
Performance issue in ODataJsonLightReader RRS feed

  • Question

  • Hi,

    I have for some time been frustrated with the bad performance I am getting in WCF DS client code when running with the Json (light) format. Finally I did some profiling of the issue and here are my findings.

    First of all my model is very large (around 400 entities with around 200 simple properties each on average and 100 reference properties).

    When I do queries against my service wthout any projections and on the Json format the client will end up using 100% CPU resources and perform really bad. Doing a profilling of the client shows that around 90% of the time is spent in this function:

    Function Name Inclusive Samples Exclusive Samples Inclusive Samples % Exclusive Samples % Module Name
    - Microsoft.Data.OData.JsonLight.ODataJsonLightReader.StartNavigationLink
    102.425 75 92,23 0,07 Microsoft.Data.OData.dll
    - Microsoft.Data.Edm.Csdl.Internal.CsdlSemantics.CsdlSemanticsEntitySet.FindNavigationTarget
    101.041 418 90,99 0,38 Microsoft.Data.Edm.dll

    IlSpy revaels the implementation of FindNavigationTarget to be something like:

    public IEdmEntitySet FindNavigationTarget(IEdmNavigationProperty property)
    {
    	CsdlSemanticsNavigationProperty csdlSemanticsNavigationProperty = property as CsdlSemanticsNavigationProperty;
    	if (csdlSemanticsNavigationProperty != null)
    	{
    		using (IEnumerator<IEdmEntityContainer> enumerator = this.Model.EntityContainers().GetEnumerator())
    		{
    			while (enumerator.MoveNext())
    			{
    				CsdlSemanticsEntityContainer csdlSemanticsEntityContainer = (CsdlSemanticsEntityContainer)enumerator.Current;
    				IEnumerable<CsdlSemanticsAssociationSet> enumerable = csdlSemanticsEntityContainer.FindAssociationSets(csdlSemanticsNavigationProperty.Association);
    				if (enumerable != null)
    				{
    					foreach (CsdlSemanticsAssociationSet current in enumerable)
    					{
    						CsdlSemanticsAssociationSetEnd csdlSemanticsAssociationSetEnd = current.End1 as CsdlSemanticsAssociationSetEnd;
    						CsdlSemanticsAssociationSetEnd csdlSemanticsAssociationSetEnd2 = current.End2 as CsdlSemanticsAssociationSetEnd;
    						if (current.End1.EntitySet == this && csdlSemanticsNavigationProperty.To == current.End2.Role)
    						{
    							this.Model.SetAssociationSetName(current.End1.EntitySet, property, current.Name);
    							if (csdlSemanticsAssociationSetEnd != null && csdlSemanticsAssociationSetEnd2 != null)
    							{
    								this.Model.SetAssociationSetAnnotations(csdlSemanticsAssociationSetEnd.EntitySet, property, current.DirectValueAnnotations, csdlSemanticsAssociationSetEnd.DirectValueAnnotations, csdlSemanticsAssociationSetEnd2.DirectValueAnnotations);
    							}
    							IEdmEntitySet result = current.End2.EntitySet;
    							return result;
    						}
    						if (current.End2.EntitySet == this && csdlSemanticsNavigationProperty.To == current.End1.Role)
    						{
    							this.Model.SetAssociationSetName(current.End2.EntitySet, property, current.Name);
    							if (csdlSemanticsAssociationSetEnd != null && csdlSemanticsAssociationSetEnd2 != null)
    							{
    								this.Model.SetAssociationSetAnnotations(csdlSemanticsAssociationSetEnd2.EntitySet, property, current.DirectValueAnnotations, csdlSemanticsAssociationSetEnd2.DirectValueAnnotations, csdlSemanticsAssociationSetEnd.DirectValueAnnotations);
    							}
    							IEdmEntitySet result = current.End1.EntitySet;
    							return result;
    						}
    					}
    				}
    			}
    		}
    	}
    	return null;
    }

    As far as I understand this code is looking thru my entire model (which is huge) to find the link endpoint AND it does that for every link property for all entities returned by the service. I understand it has to do this as the Json format doesn't include it in the payload, but it surely shouldn't do it for every property of every entity in a feed.

    Imagine a scenario wher I return 10,000 entities in a feed with an entity having 100 navigation properties - this will result in the above method being called 100x10000 = 1,000,000 times where each call will iterate the entire model trying to find the link endpoint.

    The profiling were done on 5.6.0.0 Alpha. I know this is an Alpha release, but I have experienced the same hopeless performance on all prior releases as well.

    Could you please have a look at this?

    Regards

    Uffe

       
    • Edited by Uffe Lauesen Thursday, July 11, 2013 5:41 PM Removed some wrong formating tags.
    Sunday, July 7, 2013 6:58 PM

Answers

  • Yes, we fixed it in 5.6.0.0 RC1. Please let us know if you run into more issues and we will definitely look into them and fix them. Thanks a lot for the great feedback and keep it coming.

    Thanks

    Pratik


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, July 31, 2013 5:10 PM
    Moderator

All replies

  • Hi Uffe,

    Thanks for your post. I'll try to involve some other senior engineers in this thread.

    It will take some time to get the response, you patience will be appreciated.

    Thanks for your understanding and have a nice day.

    Best regards,


    Chester Hong
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help

    Tuesday, July 9, 2013 1:44 AM
    Moderator
  • Thanks for reporting this. We have identified the issue and we are looking into ways to fix this. Again, once this is fixed, i will report back to this thread about which version this was fixed in.

    Thanks

    Pratik


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, July 16, 2013 7:23 PM
    Moderator
  • Thanks Pratik,

    I'll be happy to verify the fix as soon as you have it ready.

    Thank

    Uffe

    Thursday, July 18, 2013 12:00 PM
  • It sure looks as if it has been fixed in 5.6.0.0 rc1

    Thank you.

    Uffe

    Wednesday, July 31, 2013 2:10 PM
  • Yes, we fixed it in 5.6.0.0 RC1. Please let us know if you run into more issues and we will definitely look into them and fix them. Thanks a lot for the great feedback and keep it coming.

    Thanks

    Pratik


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, July 31, 2013 5:10 PM
    Moderator