Skip to content
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

Improve graph opening times, reduce reflecion calls #15761

Merged
merged 11 commits into from
Feb 11, 2025

Conversation

dimven-adsk
Copy link
Contributor

Purpose

This PR targets a low-hanging fruit for improving the graph open (and saving) performance by reducing the CLR reflection calls that are used for getting a node's package assembly name (used in figuring out dependencies and used packages in a graph).

These reflection calls are not insignificant and the result can be cached (because it is not possible to change a node's assembly during runtime). If that ever changes, then you can override the method :) . Furthermore, the current implementation actually ignores the existing assembly reference and instead reloads it again from the referenced location path, which seems completely pointless.

A further improvement can be made by storing only the assembly's name as a string instead of the entire AssemblyName class instance, since we're only using the name.

The hot path before:
devenv_MBWq5M7hXq

And after:
devenv_oSYjkqT8f7

Declarations

Check these if you believe they are true

  • The codebase is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated
  • This PR contains no files larger than 50 MB

Release Notes

(FILL ME IN) Brief description of the fix / enhancement. Use N/A to indicate that the changes in this pull request do not apply to Release Notes. Mandatory section

Reviewers

(FILL ME IN) Reviewer 1 (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

FYIs

(FILL ME IN, Optional) Names of anyone else you wish to be notified of

@dimven-adsk dimven-adsk changed the title remove assembly name instances Improve graph opening times, reduce reflecion calls Jan 17, 2025
Copy link

github-actions bot commented Jan 17, 2025

UI Smoke Tests

Test: success. 11 passed, 0 failed.
TestComplete Test Result
Workflow Run: UI Smoke Tests
Check: UI Smoke Tests

@mjkkirschner mjkkirschner self-assigned this Jan 17, 2025
@mjkkirschner mjkkirschner self-requested a review January 17, 2025 15:59
/// <summary>
/// The method returns the assembly name from which the node originated.
/// </summary>
/// <returns>Assembly Name</returns>
internal virtual AssemblyName GetNameOfAssemblyReferencedByNode()
internal virtual string GetNameOfAssemblyReferencedByNode()
Copy link
Member

@mjkkirschner mjkkirschner Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dimven-adsk thanks for these changes - the cache is a good idea.
What I would prefer is that unless the change from AssemlyName -> String has clear performane benefits I would say to keep the signature of these methods the same.

I assume that the real perf gain here is from the cache and not using the GetType().Assembly / strange double lookup / allocation of AssemblyName. It seems if we just cache the AssemblyName we'll get most of the benefit, though I guess the AssemblyName objects are quite wasteful at the moment though I can see us using some of these other properties in the future and I'd rather avoid spreading out the cost of allocating these later in a less predictable manner, or doing error prone string munging - thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would echo the same:
What I would prefer is that unless the change from AssemlyName -> String has clear performane benefits I would say to keep the signature of these methods the same.

@@ -1223,18 +1223,21 @@ protected NodeModel(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPo
RaisesModificationEvents = true;
}


internal string cachedAsmName = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this protected

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ANother name for the member could be
NameOfAssemblyReferencedByNode to match the existing method

if (string.IsNullOrEmpty(cachedAsmName))
{
cachedAsmName = GetType().Assembly.FullName;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could probably do it

NameOfAssemblyReferencedByNode ??= GetType().Assembly.GetName();
return NameOfAssemblyReferencedByNode;

or even

internal virtual AssemblyName GetNameOfAssemblyReferencedByNode() => NameOfAssemblyReferencedByNode ??= GetType().Assembly.GetName();

@dimven-adsk
Copy link
Contributor Author

I've implemented the feedback and reverted the code back to using the full AssemblyName. You are totally correct, there is no observable difference between using that and a string:

image

I imagine the only difference would be a few extra bytes of memory for storing the AN instances, which would be insignificant :)

@pinzart90 pinzart90 merged commit 512f789 into DynamoDS:master Feb 11, 2025
22 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants