From 3368a199cba698aa3bd8745c603f676a3d7a33a4 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Thu, 18 Aug 2022 14:07:59 +0200 Subject: [PATCH] Reduce activity threshold for non-idle threads. Fixes #4190. Now we will display more minimally-active threads by default. For the example profile in #4190, a threshold of 8% would have been sufficient to show the thread. I decided to go down to 5%, but not for any particular reason, just because it was a rounder number. Maybe we'll find out that 8% would have been better after all. Reducing this threshold won't overload the thread list, because we still have the limit of 15 threads. --- src/profile-logic/tracks.js | 6 +-- src/test/store/receive-profile.test.js | 53 +++++++++----------------- 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/src/profile-logic/tracks.js b/src/profile-logic/tracks.js index d0a7fded27..538f89687d 100644 --- a/src/profile-logic/tracks.js +++ b/src/profile-logic/tracks.js @@ -827,8 +827,8 @@ export function getLocalTrackName( } } -// Consider threads whose sample score is 20% or less of the maximum sample score to be idle. -const IDLE_THRESHOLD_FRACTION = 0.2; +// Consider threads whose sample score is less than 5% of the maximum sample score to be idle. +const IDLE_THRESHOLD_FRACTION = 0.05; // Return a non-empty set of threads that should be shown by default. export function computeDefaultVisibleThreads( @@ -867,7 +867,7 @@ export function computeDefaultVisibleThreads( // As a last pass, cull very-idle threads, by comparing their activity // to the thread with the most "sampleScore" activity. - // We keep all threads whose sampleScore is at least 20% of the highest + // We keep all threads whose sampleScore is at least 5% of the highest // sampleScore, and also any threads which are otherwise essential. const highestSampleScore = Math.max( ...scores.map(({ score }) => score.sampleScore) diff --git a/src/test/store/receive-profile.test.js b/src/test/store/receive-profile.test.js index 7301380bdc..9f72cde6e4 100644 --- a/src/test/store/receive-profile.test.js +++ b/src/test/store/receive-profile.test.js @@ -385,8 +385,8 @@ describe('actions/receive-profile', function () { const { profile } = getProfileFromTextSamples( // 2 samples of work `work work`, - // 11 samples of work - `work work work work work work work work work work work` + // 41 samples of work (2 / 41 < 0.05) + Array(41).fill('work').join(' ') ); profile.threads.forEach((thread, threadIndex) => { @@ -403,53 +403,53 @@ describe('actions/receive-profile', function () { }); describe('with threadCPUDelta', function () { - it('will show a thread when the relative CPU usage is above 20%', function () { + it('will show a thread when the relative CPU usage is above 10%', function () { const store = blankStore(); // A profile with an accumulated value of 430 in the first thread. Therefore the - // 20% threshold for a non-idle thread's accumulated CPU usage is 86. + // 10% threshold for a non-idle thread's accumulated CPU usage is 43. const profile = getProfileWithThreadCPUDelta([ [15, 20, 100, 50, 80, 40, 60, 20, 20, 25], // Thread with 430 sample score - [15, 6, 1, 11, 11, 7, 0, 12, 14, 9], // Thread with 86 sample score + [5, 6, 1, 11, 0, 7, 0, 12, 14, 0], // Thread with 56 sample score ]); profile.threads[0].name = 'Thread with 100% CPU'; - profile.threads[1].name = 'Thread with 20% CPU'; + profile.threads[1].name = 'Thread with 13% CPU'; profile.threads[0].pid = 1; profile.threads[1].pid = 1; store.dispatch(viewProfile(profile)); expect(getHumanReadableTracks(store.getState())).toEqual([ 'show [process]', - ' - show [thread Thread with 20% CPU]', // <- Ensure this thread is not hidden. + ' - show [thread Thread with 13% CPU]', // <- Ensure this thread is not hidden. ' - show [thread Thread with 100% CPU] SELECTED', ]); }); - it('will hide a thread when the relative CPU percentage is below 20%', function () { + it('will hide a thread when the relative CPU percentage is below 5%', function () { const store = blankStore(); - // A profile with an accumulated value of 430 in the first thread. Therefore the - // 20% threshold for a non-idle thread's accumulated CPU usage is 86. + // A profile with an accumulated value of 519 in the first thread. Therefore the + // 5% threshold for a non-idle thread's accumulated CPU usage is 25.95. const profile = getProfileWithThreadCPUDelta([ - [15, 20, 100, 50, 80, 40, 60, 20, 20, 25], // Thread with 430 sample score - [15, 6, 1, 31, 1, 7, 0, 2, 4, 9], // Thread with 76 sample score + [15, 20, 100, 50, 80, 40, 60, 72, 57, 25], // Thread with 519 sample score + [5, 3, 1, 4, 1, 4, 0, 2, 4, 1], // Thread with 25 sample score ]); profile.threads[0].name = 'Thread with 100% CPU'; - profile.threads[1].name = 'Thread with 10% CPU'; + profile.threads[1].name = 'Thread with 4% CPU'; profile.threads[0].pid = 1; profile.threads[1].pid = 1; store.dispatch(viewProfile(profile)); expect(getHumanReadableTracks(store.getState())).toEqual([ 'show [process]', - ' - hide [thread Thread with 10% CPU]', // <- Ensure this thread is hidden. + ' - hide [thread Thread with 4% CPU]', // <- Ensure this thread is hidden. ' - show [thread Thread with 100% CPU] SELECTED', ]); }); - it('will hide a thread when the relative CPU percentage is below 20% even if it has more samples with > 90% CPU delta', function () { + it('will hide a thread when the relative CPU percentage is below 5% even if it has more samples with > 90% CPU delta', function () { const store = blankStore(); const profile = getProfileWithThreadCPUDelta([ - [1, 2, 92, 93, 94, 1, 1, 1, 1], // Thread with 286 sample score (< 360 == 1800 * 0.2) - new Array(200).fill(9), // Thread with 200 * 9 = 1800 sample score + [1, 2, 92, 93, 94, 1, 1, 1, 1], // Thread with 286 sample score (< 315 == 6300 * 0.05) + new Array(700).fill(9), // Thread with 700 * 9 = 6300 sample score ]); profile.threads[0].name = 'Thread with a very short burst of > 90% CPU'; profile.threads[1].name = 'Thread with sustained 9% CPU'; @@ -464,25 +464,6 @@ describe('actions/receive-profile', function () { ]); }); - it('will hide a thread when the relative CPU percentage is below 20% even if it has more samples with > 10% CPU delta', function () { - const store = blankStore(); - const profile = getProfileWithThreadCPUDelta([ - [15, 20, 100, 50, 80, 40, 60, 20, 20, 25], // Thread with 430 sample score - [15, 6, 1, 31, 1, 7, 0, 2, 4, 9], // Thread with 76 sample score - ]); - profile.threads[0].name = 'Thread with 100% CPU'; - profile.threads[1].name = 'Thread with 10% CPU'; - profile.threads[0].pid = 1; - profile.threads[1].pid = 1; - - store.dispatch(viewProfile(profile)); - expect(getHumanReadableTracks(store.getState())).toEqual([ - 'show [process]', - ' - hide [thread Thread with 10% CPU]', // <- Ensure this thread is hidden. - ' - show [thread Thread with 100% CPU] SELECTED', - ]); - }); - it('will show the only thread regardless of CPU activity', function () { const store = blankStore(); const profile = getProfileWithThreadCPUDelta([