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

Client.leaveBreadcrumb is slow() #1974

Open
pyricau opened this issue Feb 6, 2024 · 3 comments
Open

Client.leaveBreadcrumb is slow() #1974

pyricau opened this issue Feb 6, 2024 · 3 comments
Labels
wip There is work in progress

Comments

@pyricau
Copy link
Contributor

pyricau commented Feb 6, 2024

Bug description

As measured on Square's hardware, Client.leaveBreadcrumb() is unreasonably slow (for what it's supposed to do, which is store a breadcrumb in a ring buffer).

Data

Here are the results, based on 175 measurements:

image

As you can see, the duration has a wide spread (up to 1 ms!) and the mode is around 173us. Even without the worst case scenario, that's a large amount of time for just adding an entry to a ring buffer.

I started looking into this after noticing that Client.leaveBreadcrumb() was showing up in our simpleperf traces. Anecdotally, it seemed like the time was spent in native code, through the JNI boundary.

Steps to reproduce

I measured the time it takes to call just Client.leaveBreadcrumb() as I navigated around our app with the following code:

measureTime {
  bugsnagClient.leaveBreadcrumb(message, metadata, MANUAL)
}

I speed compiled our app to ensure there's no jitting slowing things down with adb shell cmd package compile -f -m speed com.squareup.

Then I navigated a bunch in our app, which triggered the logging of breadcrumbs

Environment

  • Android version: Android Q (API 29)
  • Bugsnag version: 5.28.3
  • Physical device: Square hardware with sdm660 SOC
@lemnik
Copy link
Contributor

lemnik commented Feb 7, 2024

Hi @pyricau,

Thanks very much for the detailed issue, you're absolutely right that leaveBreadcrumb has a very high overhead for what it's doing. Most of this overhead indeed comes from the NDK synchronization side of things right now. The breadcrumbs data is copied several times (and in some cases is pre-json marshalled, since the native layer doesn’t currently support Lists and Maps directly) and the native ring-buffer is guarded by a global mutex, all of which is of course non-optimal.

This is an area we're actively working on at the moment (the NDK plugin also doesn't obey the maxBreadcrumbs configuration due to its current design). As part of these changes we're going to try and reduce the general overhead of breadcrumbs (removing much of the copying and locking).

For now it’s worth avoiding leaving “complex” breadcrumb metadata where it can be avoided, while we work to reduce the overhead more generally.

@mclack mclack added the wip There is work in progress label Feb 7, 2024
@lemnik
Copy link
Contributor

lemnik commented Apr 16, 2024

Hi again @pyricau

Just to let you know we've released the first improvements to the breadcrumb performance work as part of v6.4.0.

This first change will only affect breadcrumbs that have complex metadata, and was caused by a regex pattern being compiled for each metadata item instead of being shared.

We're also working on some more general performance improvements that will affect all breadcrumbs synchronized to the native layer.

@pyricau
Copy link
Contributor Author

pyricau commented Apr 17, 2024

thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wip There is work in progress
Projects
None yet
Development

No branches or pull requests

3 participants