Skip to content

Conversation

@laszlocsomor
Copy link
Contributor

Some of the getters (getCriticalPath(), etc.) used to run in O(N) for N=threads.size(); now they are O(1) because we precompute what they'd return.

Also, BazelProfile's members are no longer mutable, meaning we can safely precompute the values without fear of staleness.

@laszlocsomor laszlocsomor requested a review from afrueda97 October 9, 2025 15:08
@laszlocsomor laszlocsomor force-pushed the laszlo-precomp branch 3 times, most recently from ab6e1c8 to 51837ad Compare October 9, 2025 19:08
Comment on lines 172 to 180
for (ProfileThread e : threads.values()) {
if (mainThread == null && isMainThread(e)) {
mainThread = e;
} else if (criticalPath == null && isCriticalPathThread(e)) {
criticalPath = e;
} else if (gcThread == null && isGarbageCollectorThread(e)) {
gcThread = e;
}
}

Choose a reason for hiding this comment

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

Why e? Why not t for "thread"?

Copy link
Contributor Author

@laszlocsomor laszlocsomor Oct 13, 2025

Choose a reason for hiding this comment

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

"e" for element. It makes no difference though.

Choose a reason for hiding this comment

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

I'm assuming the question comes from e usually referring to an Exception?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can just use t.

Comment on lines 190 to 191
ImmutableMap.copyOf(otherData),
ImmutableMap.copyOf(threads),

Choose a reason for hiding this comment

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

For large profiles these copies are very costly (in terms of memory usage). How about we use Java's built-in Collections.unmodifiableMap instead to avoid copying the underlying data.

Copy link
Contributor Author

@laszlocsomor laszlocsomor Oct 13, 2025

Choose a reason for hiding this comment

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

Can you give more details, and what your concern is based on? How big do these maps get, what have you seen in the wild?

Sure, we can use unmodifiableMap. FWIW I could even use an ImmutableMap.Builder for otherData, but not for threads because we need to look up things while also building, and the ImmutableMap.Builder doesn't allow that.

Choose a reason for hiding this comment

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

OH! That's my bad, I misread and thought this was (threadId) -> (List<Event>). It's not, sorry about that. I think ImmutableMap.copyOf is fine here.

@laszlocsomor
Copy link
Contributor Author

ping

Copy link

@iamricard iamricard left a comment

Choose a reason for hiding this comment

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

Sorry for the delay @laszlocsomor 🫠

Comment on lines 190 to 191
ImmutableMap.copyOf(otherData),
ImmutableMap.copyOf(threads),

Choose a reason for hiding this comment

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

OH! That's my bad, I misread and thought this was (threadId) -> (List<Event>). It's not, sorry about that. I think ImmutableMap.copyOf is fine here.

Comment on lines 172 to 180
for (ProfileThread e : threads.values()) {
if (mainThread == null && isMainThread(e)) {
mainThread = e;
} else if (criticalPath == null && isCriticalPathThread(e)) {
criticalPath = e;
} else if (gcThread == null && isGarbageCollectorThread(e)) {
gcThread = e;
}
}

Choose a reason for hiding this comment

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

I'm assuming the question comes from e usually referring to an Exception?

Some of the getters (getCriticalPath(), etc.) used to run in O(N) for
N=threads.size(); now they are O(1) because we precompute what they'd
return.

Also, BazelProfile's members are no longer mutable, meaning we can
safely precompute those values without fear of staleness.

Signed-off-by: László Csomor <laszlo@engflow.com>
Copy link
Contributor Author

@laszlocsomor laszlocsomor left a comment

Choose a reason for hiding this comment

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

PTAL -- rebasing lead to significant changes

What's new:

  • otherData is now called otherDataBuilder and it's an ImmutableMap.Builder
  • The Stream-based computation of threads (from main branch) is gone; we compute the map with threadsMapBuilder in the same for-loop as that looking for the special threads.

@laszlocsomor
Copy link
Contributor Author

Thanks @iamricard !

@laszlocsomor laszlocsomor merged commit 85e1721 into main Oct 15, 2025
3 checks passed
@laszlocsomor laszlocsomor deleted the laszlo-precomp branch October 15, 2025 11:34
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.

4 participants