-
Notifications
You must be signed in to change notification settings - Fork 64
[ApiXmlAdjuster] Use different data model structures for better performance #756
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| // It's debatable whether we handle this "properly", as most callers just | ||
| // do `First ()`, but it's been working for years so I'm not changing it. | ||
| // Exposes an IReadOnlyDictionary so caller cannot bypass our AddType/RemoveType code. | ||
| public IReadOnlyDictionary<string, List<JavaType>> Types { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…alternatively, should this be Set<JavaType> instead of List<JavaType>? Does it make sense to allow for the same instance to be added multiple times?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same "compatibility"/"diff minimization" question/concern applies to Types vs. AllTypes: I suspect that if Types became an IEnumerable<JavaType> property and AllTypes were the "Dictionary-like" property, fewer changes would be required.
|
IMO, the changed I added |
|
|
||
| public partial class JavaPackage | ||
| { | ||
| private Dictionary<string, List<JavaType>> types = new Dictionary<string, List<JavaType>> (StringComparer.OrdinalIgnoreCase); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Java type names are not filesystem-bound constructs; they are case sensitive, and it is entirely valid to have a package example and package Example in the same app. (It'll cause pain & suffering on case-insensitive filesystems! But Java allows it.)
I think this should use StringComparer.Ordinal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, fixed.
| if (reader.LocalName == "class") { | ||
| var kls = new JavaClass (package) { IsReferenceOnly = isReferenceOnly }; | ||
| kls.Load (reader); | ||
| package.Types.Add (kls); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…back on the "smaller diffs!" front, if we did have a class JavaTypes : KeyedCollection<string, JavaType> class, this statement wouldn't need to change, nor the many other statements just like it…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested out KeyedCollection, but it cannot handle duplicate keys:
System.ArgumentException: 'An item with the same key has already been added. Key: key1'
Today, our ApiXmlAdjuster process builds an in-memory model of every Java type we know about, and then queries this model many times in order to ensure we can resolve every needed Java type to build a binding. The data structure of this model is:
Then it is queried using LINQ like this:
In the random GPS package I used for testing,
JavaApicontained 310 packages and a total of 5941 types. Repeatedly looping through them looking for the correct type takes a considerable amount of time.Instead, we can use a
Dictionaryto store packages and types keyed by name to significantly speed up type resolution:For the GPS project, this reduced time taken considerably:
The only "interesting" detail is that we can have multiple types with the same Java name, such as
MyInterfaceandMyInterfaceConsts. Thus we need to useDictionary<string, List<JavaType>>to ensure we collect them all.For good measure I ran a XA build with this to ensure
Mono.AndroidApiCompatdidn't find any issues: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=4282925.