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

perf: optimize some conversions of unsigned ints to NSString #2863

Merged

Conversation

armcknight
Copy link
Member

@armcknight armcknight commented Apr 5, 2023

Some work done in a tight loop on the profiler's sampling thread used inefficient methods to convert integers to strings. We sped this up by using snprintf.

Targets to optimize:

  • boxing unsigned integers to NSNumbers and converting to NSString with -[NSNumber stringValue]
  • boxing to NSNumber and calling sentry_formatHexAddress which called +[NSString stringWithFormat:]
  • directly formatting an unsigned int to a string with [NSString stringWithFormat:@"%llu"

Observed a 75% reduction in cost of doing the conversions using Instruments, just in the profiler's sampling thread: https://www.notion.so/sentry/formatHexAddress-perf-optimization-6ce9e406e53b4d99aed2de591428599b?pvs=4

Converted a couple other usages in the SDK to also use the new function, so we get some other perf wins for free. There are still numerous usages of the older sentry_formatHexAddress(NSNumber *) that are using values from JSON-decoded NSDictionary instances in SentryCrashReportConverter, which could be a possible target for future optimizations by the Cocoa team.

TODO

#skip-changelog

@github-actions
Copy link

github-actions bot commented Apr 5, 2023

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1253.18 ms 1270.40 ms 17.22 ms
Size 20.76 KiB 434.65 KiB 413.88 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
c00eafe 1198.26 ms 1227.62 ms 29.36 ms
ecd9ecd 1241.28 ms 1260.35 ms 19.07 ms
8526e93 1228.24 ms 1239.14 ms 10.90 ms
2cf1b84 6265.25 ms 6277.98 ms 12.73 ms
efb2222 1256.44 ms 1278.90 ms 22.46 ms
aa27ac0 1214.02 ms 1227.42 ms 13.40 ms
d60f70a 1219.63 ms 1228.54 ms 8.91 ms
ea73af6 1241.69 ms 1252.96 ms 11.27 ms
9ef729b 1228.79 ms 1245.36 ms 16.57 ms
e79ead7 1233.39 ms 1255.52 ms 22.13 ms

App size

Revision Plain With Sentry Diff
c00eafe 20.76 KiB 432.87 KiB 412.11 KiB
ecd9ecd 20.76 KiB 420.23 KiB 399.47 KiB
8526e93 20.76 KiB 420.22 KiB 399.47 KiB
2cf1b84 20.76 KiB 431.91 KiB 411.15 KiB
efb2222 20.76 KiB 424.45 KiB 403.69 KiB
aa27ac0 20.76 KiB 432.21 KiB 411.45 KiB
d60f70a 20.76 KiB 430.97 KiB 410.21 KiB
ea73af6 20.76 KiB 425.76 KiB 404.99 KiB
9ef729b 20.76 KiB 432.88 KiB 412.12 KiB
e79ead7 20.76 KiB 426.11 KiB 405.35 KiB

Previous results on branch: armcknight/perf/speed-up-profiler-hex-address-formatting

Startup times

Revision Plain With Sentry Diff
69f3d5b 1243.90 ms 1250.70 ms 6.80 ms
b506df4 1271.62 ms 1273.61 ms 1.99 ms
5854c18 1245.02 ms 1256.52 ms 11.50 ms
8e69b81 1203.33 ms 1229.88 ms 26.55 ms
8b72bae 1220.41 ms 1257.62 ms 37.21 ms
f5bcb8f 1219.49 ms 1240.94 ms 21.45 ms

App size

Revision Plain With Sentry Diff
69f3d5b 20.76 KiB 430.69 KiB 409.93 KiB
b506df4 20.76 KiB 433.00 KiB 412.24 KiB
5854c18 20.76 KiB 433.07 KiB 412.31 KiB
8e69b81 20.76 KiB 431.87 KiB 411.11 KiB
8b72bae 20.76 KiB 432.08 KiB 411.32 KiB
f5bcb8f 20.76 KiB 431.87 KiB 411.11 KiB

@armcknight armcknight marked this pull request as draft April 5, 2023 07:11
@armcknight armcknight force-pushed the armcknight/perf/speed-up-profiler-hex-address-formatting branch 2 times, most recently from 33cbb19 to 9781a6b Compare April 6, 2023 03:51
@armcknight armcknight force-pushed the armcknight/perf/speed-up-profiler-hex-address-formatting branch from 9781a6b to 22d47ab Compare April 6, 2023 04:40
Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

I'm surprised that snprintf is much faster than sentry_formatHexAddress. Thanks for the improvement.

Tests/SentryTests/SentryFormatterTests.swift Outdated Show resolved Hide resolved
Sources/Sentry/include/SentryFormatter.h Show resolved Hide resolved
@armcknight
Copy link
Member Author

I'm surprised that snprintf is much faster than sentry_formatHexAddress. Thanks for the improvement.

I think it comes down to all the extra allocations around NSStrings (even for the literal format string) and conversion of NSNumber back to an unsigned long long, both of which are avoided in the new version (and avoiding boxing the ull's to NSNumbers in the first place solely to pass them to this function is an extra benefit).

Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

@armcknight, what's stopping us from making this ready for review?

@armcknight armcknight marked this pull request as ready for review April 24, 2023 22:00
@armcknight
Copy link
Member Author

@philipphofmann this one's ready for you now!

Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

Thanks, @armcknight, for this performance improvement 👏 😃 . The changelog needs some fixes, I believe. LGTM.

@@ -5,6 +5,7 @@
### Fixes

- Ensure the current GPU frame rate is always reported for concurrent transaction profiling metrics (#2929)
- Improved performance serializing profiling data (#2863)
Copy link
Member

Choose a reason for hiding this comment

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

m: I think that needs to move up a bit.

Copy link
Member Author

Choose a reason for hiding this comment

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

Are you looking at ordering by PR number? I haven't really cared about it too much, but am happy to start.

Copy link
Member

Choose a reason for hiding this comment

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

No, I thought the entry was in an already-released section, but I maybe was mistaken; sorry.

@armcknight
Copy link
Member Author

The only CI failures were codecov, but only because the test coverage was not properly assessed for the header implementations. There is indeed test coverage for them.

@armcknight armcknight merged commit c0ff306 into main Apr 25, 2023
@armcknight armcknight deleted the armcknight/perf/speed-up-profiler-hex-address-formatting branch April 25, 2023 19:25
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.

2 participants