Skip to content
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

[Bug]: Critical path is taxing on CPU when expanding span tags #2179

Open
bobrik opened this issue Feb 20, 2024 · 6 comments
Open

[Bug]: Critical path is taxing on CPU when expanding span tags #2179

bobrik opened this issue Feb 20, 2024 · 6 comments

Comments

@bobrik
Copy link
Contributor

bobrik commented Feb 20, 2024

What happened?

We upgraded from v1.46 to v1.54 and some users noticed slowness when expanding tags. With some CPU tracing I was able to pinpoint #1871 as the culprit.

Steps to reproduce

  1. Run Jaeger v1.54
  2. Load a large trace
  3. Try expanding/collapsing spans
  4. Observe slowness

Expected behavior

Everything is snappy as it was.

Relevant log output

No response

Screenshot

image image

Additional context

No response

Jaeger backend version

v1.54

SDK

No response

Pipeline

No response

Stogage backend

No response

Operating system

No response

Deployment model

No response

Deployment configs

No response

@bobrik bobrik added the bug label Feb 20, 2024
@bobrik bobrik changed the title [Bug]: Critical path is taxing on CPU when expanding span tags in large traces [Bug]: Critical path is taxing on CPU when expanding span tags Feb 20, 2024
@MiirzaBaig
Copy link

Is it still on?
if yes would like to work on this!

@yurishkuro
Copy link
Member

yes, there is an unfinished PR

@MiirzaBaig
Copy link

noted!

@BenzeneAlcohol
Copy link
Contributor

This is happening because mergeChildrenCritialPath has a recursive function findAllDescendants that keeps calling descendents (children) of the span. In the wort case, each span could be checked once and hence the time complexity here is already O(n^2). And then filtering and merging adds some extra time.

We could simplify this by using a map, that stores the spans. This will take O(n) to create, but once created search operations would be processed in constant time. Now, using a stack we can push all the spans into the stack. If they have a child, they are pushed as well. In O(n) time we can evaluate the stack, and an O(m) time to filter and merge. Makes the time complexity better than the previous approach.

I can give a detailed explanation in the PR, if this idea sounds good and I can proceed.

cc: @yurishkuro

@yurishkuro
Copy link
Member

@BenzeneAlcohol pre-building a map makes total sense. However, you may notice that we already build a tree when loading a trace (packages/jaeger-ui/src/selectors/trace.tsx). I would really like to have a way where that tree is not thrown away but reused for critical path and any other visitors. I think we keep rebuilding this tree multiple times for every trace.

@BenzeneAlcohol
Copy link
Contributor

Yeah, I looked into it. I'll come up with an algo later today or tomorrow and post it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants