Skip to content

[PERFORMANCE] Various small enhancements detected thanks to flame graphs - #435

Merged
chibenwa merged 7 commits into
apache:masterfrom
chibenwa:flame-graph-opts
May 18, 2021
Merged

[PERFORMANCE] Various small enhancements detected thanks to flame graphs#435
chibenwa merged 7 commits into
apache:masterfrom
chibenwa:flame-graph-opts

Conversation

@chibenwa

Copy link
Copy Markdown
Contributor

Screenshot from 2021-05-16 17-45-01

Here we can see a call to MessageResultImpl::getMessageId responsible of 0.78% of the total allocated memory... Rationals are that and intermediate (uneeded) on the fly messageMetadata is used, which includes an (innefficient) flag copy.

Screenshot from 2021-05-16 17-51-05

Here is a flame graph capture showing the costs of initializing JMAP routes for each requests.

@chibenwa chibenwa self-assigned this May 16, 2021
@chibenwa

Copy link
Copy Markdown
Contributor Author

Screenshot from 2021-05-16 22-41-50

0.26% CPU resources on formatting a validation message...

@chibenwa

Copy link
Copy Markdown
Contributor Author

Screenshot from 2021-05-17 07-46-15

0.56% running an inefficient algorithm to state which mailboxes have kids, in O(n2). While the percentage is low acting on it with likely improve p99 for Mailbox/get with many mailboxes and is thus worth writing.

@chibenwa

chibenwa commented May 17, 2021

Copy link
Copy Markdown
Contributor Author

I confirm the last fixups regarding "computing metadata" do not cost performance.

Screenshot from 2021-05-17 18-20-38

chibenwa added 7 commits May 18, 2021 12:38
This method is responsible of ~2% of total memory allocation
as per async-profiler and the builder is the main guilty:

Its advanced flags filtering capability, not needed for a
copy use case come at a high cost.
By calling `messageMetadata` too frequently we generate too
much flag copies that are responsible of over 2% of total
memory allocation as per async-profiler.
…wice

Field::getBody already perform the operation hence there is
no need for it. Async-profiler indicates we spend 0.2% of
the CPU needlessly that way... Minor but always good to take!
It was generating it for each requests. Each endpoints needs
to initialize its own URI parser.

Also the version was parsed for each routes and not just
once per request.
String.format was evaluated on each Version and cost 0.26% of total
CPU time budget.
…sChildren

0.56% running an inefficient algorithm to state which mailboxes have kids, in O(n2). While the percentage is low acting on it with likely improve p99 for `Mailbox/get` with many mailboxes and is thus worth writing.
Filters are dependent of client request, requiring ObjectMapper reconfiguration
as object mapper configuration changes are not thread safe.

However ObjectMapper javadoc states the following:

```
Method is typically
used when multiple, differently configured mappers are needed.
Although configuration is shared, cached serializers and deserializers
are NOT shared, which means that the new instance may be re-configured
before use; meaning that it behaves the same way as if an instance
was constructed from scratch.
```

This sounds like our use case!

This conforts to advices of this page: https://github.com/FasterXML/jackson-docs/wiki/Presentation:-Jackson-Performance

```
Reuse heavy-weight objects: ObjectMapper (data-binding) and JsonFactory (streaming API)
```
@chibenwa
chibenwa force-pushed the flame-graph-opts branch from c4a5602 to b64aeb0 Compare May 18, 2021 05:47
@chibenwa
chibenwa merged commit 1542cba into apache:master May 18, 2021
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