diff --git a/src/bgen/DocumentationManager.cs b/src/bgen/DocumentationManager.cs index 8b8a29851b3..bd9f3e8c18e 100644 --- a/src/bgen/DocumentationManager.cs +++ b/src/bgen/DocumentationManager.cs @@ -10,14 +10,25 @@ public class DocumentationManager { string xml; - XmlDocument? doc; + Dictionary? memberLookup; public DocumentationManager (string assembly) { this.xml = Path.ChangeExtension (assembly, ".xml"); if (File.Exists (xml)) { - doc = new XmlDocument (); + var doc = new XmlDocument (); doc.LoadWithoutNetworkAccess (xml); + // Pre-build a dictionary for O(1) member lookups instead of + // O(n) XPath queries on every TryGetDocumentation call. + var members = doc.SelectNodes ("/doc/members/member[@name]"); + if (members is not null) { + memberLookup = new Dictionary (members.Count); + foreach (XmlNode member in members) { + var name = member.Attributes? ["name"]?.Value; + if (name is not null) + memberLookup [name] = member; + } + } } } @@ -38,14 +49,13 @@ public bool TryGetDocumentation (MemberInfo member, [NotNullWhen (true)] out str { documentation = null; - if (doc is null) + if (memberLookup is null) return false; if (!TryGetId (member, out var id)) return false; - var node = doc.SelectSingleNode ($"/doc/members/member[@name='{id}']"); - if (node is null) + if (!memberLookup.TryGetValue (id, out var node)) return false; if (transformNode is not null)