Skip to content

performance profiling of first load of trace data #9465

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

Merged
merged 6 commits into from
Feb 6, 2019

Conversation

mjkkirschner
Copy link
Member

@mjkkirschner mjkkirschner commented Jan 31, 2019

Purpose

Element binding is very slow on first run when the size of the element binding data is greater than a few entires.

This change attempts to avoid the exponential cost of looping over all types in all assemblies to find a matching type name - instead we first try to look in assemblies that match in name only, then fallback to our slow matching strategy.

you can see in the below timeline profile that running the sample graph on first load took ~2.5 minutes and after this change runtime is ~25 seconds.

before:
screen shot 2019-01-31 at 3 44 58 pm

after:
screen shot 2019-01-31 at 3 48 29 pm

TODO:

  • add tests

Declarations

Check these if you believe they are true

  • The code base 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.

Reviewers

@aparajit-pratap
@saintentropy

FYIs

@smangarole

@mjkkirschner mjkkirschner changed the title first try performance profiling of first load of trace data Jan 31, 2019
@aparajit-pratap
Copy link
Contributor

@mjkkirschner I've added a test.

@mjkkirschner
Copy link
Member Author

@aparajit-pratap thanks! I will build on top of this test with a large element binding example of the scale which replicates the issue.

add new test file with 1500 trace elements
make traceBinder internal
expose protoCore internals to dynamoCoreTests
@mjkkirschner
Copy link
Member Author

@saintentropy @aparajit-pratap @QilongTang I have done the following:

  • re-enabled the existing callsite tests that were marked failure after getting them to pass
  • added traceBinder unit tests
  • added a perf test that asserts loading trace data for 1500 elements is accomplished in < 20 seconds. Currently this takes ~~2 seconds after this pr with my local set of assemblies.

PTAL


BeginRun();
sw.Stop();
Assert.Less(sw.Elapsed.Milliseconds, 20000);
Copy link
Contributor

@aparajit-pratap aparajit-pratap Feb 6, 2019

Choose a reason for hiding this comment

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

How much time would this take earlier, 20s? This time could be hardware specific. I don't think it takes 20s for me without your fixes.

Copy link
Member Author

@mjkkirschner mjkkirschner Feb 6, 2019

Choose a reason for hiding this comment

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

I will check - with the sample files I was using with similar sized data it took 2.5 minutes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, it took over a min when I ran it again. I might have made a mistake running it the first time. It looked a lot faster then. I think testing for <20s shouldn't be a problem on most machines if you claim that it actually takes just 2s.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious what the existing tests tested (the ones you re-enabled)? LGTM!

Copy link
Member Author

Choose a reason for hiding this comment

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

The tests also do some really simple element binding and element disposal testing.

@aparajit-pratap aparajit-pratap added the LGTM Looks good to me label Feb 6, 2019
@mjkkirschner
Copy link
Member Author

@aparajit-pratap on my vm - the loading of trace in this test takes 34 seconds before the change, after it takes 1.1 seconds - I ran them both a few times, this appears to be the average on my machine.

@mjkkirschner mjkkirschner merged commit 97e4e20 into DynamoDS:master Feb 6, 2019
@dimven
Copy link
Contributor

dimven commented Feb 8, 2019

@mjkkirschner while these changes are great and will improve the deserialization of all kinds of custom classes that people have decided to save to their dynamo graph, isn't serializing the entire wrapped object for each bound element too much? I was just wondering if a special and more light-weight method could be implemented for those cases, one that stores only the unique id of the element as a string? Right now every public member of the wrapped object will get serialized, when all we need is the guid. All other parameters might have changed between the time the graph was saved last and the latest version of the Revit model it was used with and that would most likely invalidate the trace data.

If that's viable, it could hopefully improve both the robustness and the performance of element binding in general.

@mjkkirschner
Copy link
Member Author

mjkkirschner commented Feb 15, 2019

Hi @dimven Right now every public member of the wrapped object will get serialized, when all we need is the guid. this is not the case - in trace we only serialize the serializeableID class which is usually just an id - Directshapes serialize a bit more info. Unfortunately this uses SOAP formatter serialization which serializes a bunch of other info required for deserialization based on specific assembly version etc. The data is also base 64 encoded which actually makes it larger...

So your initial point is definitely valid, it's just maybe not as bad initially - or bad in other ways 😄 .

You can see what's in trace by base64 decoding it, and then base 64 decoding the individual elements again.

@dimven
Copy link
Contributor

dimven commented Feb 15, 2019

Thanks for shining a light of things. A single element serializes to this:

<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:SerializableId id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/RevitServices.Persistence/RevitServices%2C%20Version%3D2.0.2.6833%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<stringID id="ref-3">2ffe7cec-9741-4601-97ab-442840b4bec8-001158a3</stringID>
<intID>1136803</intID>
</a1:SerializableId>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

which is about 750 characters on average. That means that roughly for every 700 elements serialized to a dyn file you save something the size of an average novel :D

If we could save just the GUID strings maybe as json, that'd be a reduction of over 90%

mjkkirschner added a commit to mjkkirschner/Dynamo that referenced this pull request Feb 20, 2019
* add element binding test to core
* re-enabe callsite tests, update files, and load deps manually
* add timing test
add new test file with 1500 trace elements
make traceBinder internal
expose protoCore internals to dynamoCoreTests
mjkkirschner added a commit that referenced this pull request Feb 21, 2019
…#9505)

* performance profiling of first load of trace data (#9465)

* add element binding test to core
* re-enabe callsite tests, update files, and load deps manually
* add timing test
add new test file with 1500 trace elements
make traceBinder internal
expose protoCore internals to dynamoCoreTests

* modify file versions so they are not from the future
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LGTM Looks good to me
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants