Skip to content
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions Assets/Tests/InputSystem/CorePerformanceTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;
Expand All @@ -12,6 +13,7 @@
using UnityEngine.InputSystem.Users;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.TestTools;
using static System.Collections.Specialized.BitVector32;

////TODO: add test for domain reload logic

Expand Down Expand Up @@ -1100,4 +1102,106 @@ public void Performance_OptimizedControls_ReadingPose4kTimes(OptimizationTestTyp
}

#endif

#if UNITY_2022_3_OR_NEWER
[PrebuildSetup(typeof(ProjectWideActionsBuildSetup))]
[PostBuildCleanup(typeof(ProjectWideActionsBuildSetup))]
[UnityTest, Performance]
[Category("Performance")]
public IEnumerator Performance_MeasureInputSystemFrameTimeWithProfilerMarkers_FPS()
{
string[] markers =
{
"InputUpdate",
"InputSystem.onBeforeUpdate",
"InputSystem.onAfterUpdate",
"PreUpdate.NewInputUpdate",
"PreUpdate.InputForUIUpdate",
"FixedUpdate.NewInputFixedUpdate"
};

var keyboard = InputSystem.AddDevice<Keyboard>();
var mouse = InputSystem.AddDevice<Mouse>();

var moveAction = InputSystem.actions.FindAction("Move");
var lookAction = InputSystem.actions.FindAction("Look");
var attackAction = InputSystem.actions.FindAction("Attack");
var jumpAction = InputSystem.actions.FindAction("Jump");
var sprintAction = InputSystem.actions.FindAction("Sprint");

int performedCallCount = 0;

moveAction.performed += context => {
performedCallCount++;
};

lookAction.performed += context => {
performedCallCount++;
};

attackAction.performed += context => {
performedCallCount++;
};

jumpAction.performed += context => {
performedCallCount++;
};

sprintAction.performed += context => {
performedCallCount++;
};

using (Measure.ProfilerMarkers(markers))
{
for (int i = 0; i < 500; ++i)
{
PressAndRelease(keyboard.wKey, queueEventOnly: true);
Copy link
Collaborator

Choose a reason for hiding this comment

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

On the other hand (compared to comment below), pressing W, A, S and D as well as shift and space and mouse button at a constant rate of e.g. 60 times per second is not very realistic? I would suggest to use a modulo operation here with a switch to do different input for each frame depending on a modulo computation, e.g. if (i % 60 == 0) PressSomething()
would mean I press something every 60th frame, which means once a second if playing at 60 Hz. If benchmark is targeting something specific (microbenchmark) it may make sense to stick to large data amount though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

PressAndRelease(keyboard.aKey, queueEventOnly: true);
PressAndRelease(keyboard.sKey, queueEventOnly: true);
PressAndRelease(keyboard.dKey, queueEventOnly: true);

PressAndRelease(keyboard.leftShiftKey, queueEventOnly: true);

PressAndRelease(keyboard.spaceKey, queueEventOnly: true);

Click(mouse.leftButton, queueEventOnly: true);

//mouse movements for higher polling mice (66*60 ~ 4kHz)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the for loop here should match the achievable event rate at the OS. So 66 here like you are using means 66 Hz. I think 500-1000 Hz is common as hardware sampling frequency. The maximum I have measured on my machine with a 8 kHZ mouse have been 5700 mouse events per second. Which means 95 mouse events per frame @60 Hz. So that would map to 95 here in this for. The outer for loop just means, lest simulate 500 frames.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

for (int j = 0; j < 66; ++j)
{
Move(mouse.position, new Vector2(i + j, i + j), queueEventOnly: true);
}

InputSystem.Update();

yield return null;
}
}
}

[PrebuildSetup(typeof(ProjectWideActionsBuildSetup))]
[PostBuildCleanup(typeof(ProjectWideActionsBuildSetup))]
[UnityTest, Performance]
[Category("Performance")]
public IEnumerator Performance_MeasureInputSystemFrameTimeWithProfilerMarkers_DoingNothing()
{
string[] markers =
{
"InputUpdate",
"InputSystem.onBeforeUpdate",
"InputSystem.onAfterUpdate",
"PreUpdate.NewInputUpdate",
"PreUpdate.InputForUIUpdate",
"FixedUpdate.NewInputFixedUpdate"
};

yield return Measure.Frames()
.WarmupCount(30)
.DontRecordFrametime()
.MeasurementCount(500)
.ProfilerMarkers(markers)
.Run();
}

#endif
}