Skip to content

Assorted perf improvements in hot code paths#10601

Merged
keveleigh merged 14 commits into
microsoft:prerelease/2.8.0from
keveleigh:hand-perf
May 23, 2022
Merged

Assorted perf improvements in hot code paths#10601
keveleigh merged 14 commits into
microsoft:prerelease/2.8.0from
keveleigh:hand-perf

Conversation

@keveleigh

Copy link
Copy Markdown
Contributor

Overview

These traces are using in-editor remoting.

Before:
image

After:
image

  • Updated several hand joint code paths to prefer arrays over dictionaries
  • Cached various for loop end conditions, so we don't continually query properties or Length or Count values
  • Cached a handful of CoreServices calls in hot loops
  • Updated several pointers to return early from OnPreSceneQuery if they aren't enabled and their enabled state doesn't depend on work in OnPreSceneQuery

@keveleigh keveleigh added this to the MRTK 2.8 milestone May 20, 2022
@keveleigh keveleigh requested a review from RogPodge May 20, 2022 00:18
@keveleigh keveleigh self-assigned this May 20, 2022
@keveleigh

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 2 pipeline(s).

Comment thread Assets/MRTK/SDK/Features/UX/Scripts/Pointers/LinePointer.cs Outdated
… patterns

Currently, there are two InputDevices: one with interaction data and one with hand joint data. Going forward, there may only be one 👀
@keveleigh

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 2 pipeline(s).

Comment thread Assets/MRTK/Providers/Windows/WindowsSpeechInputProvider.cs
Comment thread Assets/MRTK/Providers/Windows/WindowsSpeechInputProvider.cs
using (UpdateCurrentIndexPosePerfMarker.Auto())
{
if (unityJointPoses.TryGetValue(TrackedHandJoint.IndexTip, out currentIndexPose))
if (unityJointPoses != null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it the case that if we can't get one joint, we can't get any of them? I think these cases were originally supposed to just check if specific joints were unavailable, while this change checks if any were reported at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's true...this does add an "all or nothing" assumption to the internals.
I have another approach around defining a new IDictionary type that's backed by an array, and then maybe we return pose != default(MixedRealityPose) or something. I can go down that path quickly and see the perf comparisons.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is the last thing that caught my eye in this PR. I think if we can avoid doing the all or nothing that'd be preferrable, though I'm willing to let the behavior fall through here if it's a small edge case and we get lots of perf improvement

public void UpdateVelocity()
{
if (unityJointPoses.TryGetValue(TrackedHandJoint.Palm, out var currentPalmPose))
if (unityJointPoses != null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1 on the joint question.

@keveleigh

Copy link
Copy Markdown
Contributor Author

/azp run

@microsoft microsoft deleted a comment from azure-pipelines Bot May 23, 2022
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@david-c-kline david-c-kline left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Good changes! Just a few nitpicks / readability comments

get
{
if (!unityJointPoses.TryGetValue(TrackedHandJoint.Palm, out var palmPose)) return false;
if (unityJointPoses == null) return false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: can you add { } around the return statement?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated!

unityJointPoses = jointPoses;
CoreServices.InputSystem?.RaiseHandJointsUpdated(InputSource, Handedness, unityJointPoses);

if (unityJointPoses == null) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: can you add { }?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated!

case HandJoint.LittleTip: return TrackedHandJoint.PinkyTip;

default: return TrackedHandJoint.None;
case HandJoint.Palm: return (int)TrackedHandJoint.Palm;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

maybe consider using a variable here and casting in a separate return statement? not critical, but might be a little easier to read w/o every line having a cast

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated!

case HandFinger.Ring: return TrackedHandJoint.RingMetacarpal + index;
case HandFinger.Pinky: return TrackedHandJoint.PinkyMetacarpal + index;
default: return TrackedHandJoint.None;
case HandFinger.Thumb: return (index == 0) ? (int)TrackedHandJoint.Wrist : (int)TrackedHandJoint.ThumbMetacarpalJoint + index - 1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

same as above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated!

case HandFinger.Ring: return TrackedHandJoint.RingMetacarpal + index;
case HandFinger.Pinky: return TrackedHandJoint.PinkyMetacarpal + index;
default: return TrackedHandJoint.None;
case HandFinger.Thumb: return (index == 0) ? (int)TrackedHandJoint.Wrist : (int)TrackedHandJoint.ThumbMetacarpalJoint + index - 1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

same casting comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated!

{
using (OnPreSceneQueryPerfMarker.Auto())
{
if (!IsInteractionEnabled) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: please add { }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated!

{
using (OnPreSceneQueryPerfMarker.Auto())
{
if (!IsInteractionEnabled) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: { } please

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated!

{
using (OnPreSceneQueryPerfMarker.Auto())
{
if (!IsInteractionEnabled) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: one more { }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated!

@keveleigh

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@keveleigh keveleigh merged commit d39f98c into microsoft:prerelease/2.8.0 May 23, 2022
@keveleigh keveleigh deleted the hand-perf branch May 23, 2022 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants