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

Improve the performance of rcutils_logging_format_message. #372

Merged
merged 1 commit into from
Aug 11, 2022

Conversation

clalancette
Copy link
Contributor

In particular, the g_rcutils_logging_output_format_string
can't really change after initialization time, so we don't
need to reparse it every time. Instead, parse it once at
the beginning and just maintain an array of callbacks to
call to fill in the information as each log message comes in.

In my testing, this reduces the cost of calling
rcutils_logging_format_message by about 50% in all cases, from
very short format strings to very long ones.

Format strings with many, many token substitutions are still
very inefficient. That's because once we go beyond the
fixed 2048 buffer limit and start allocating memory, we only
allocate small chunks of memory at a time. However, this
won't come up in most normal situations (including the default
format message), so we ignore this performance problem for now.

Signed-off-by: Chris Lalancette clalancette@openrobotics.org

In particular, the g_rcutils_logging_output_format_string
can't really change after initialization time, so we don't
need to reparse it every time.  Instead, parse it once at
the beginning and just maintain an array of callbacks to
call to fill in the information as each log message comes in.

In my testing, this reduces the cost of calling
rcutils_logging_format_message by about 50% in all cases, from
very short format strings to very long ones.

Format strings with many, many token substitutions are still
very inefficient.  That's because once we go beyond the
fixed 2048 buffer limit and start allocating memory, we only
allocate small chunks of memory at a time.  However, this
won't come up in most normal situations (including the default
format message), so we ignore this performance problem for now.

Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
@ivanpauno ivanpauno added the enhancement New feature or request label Aug 10, 2022
Copy link
Member

@ivanpauno ivanpauno left a comment

Choose a reason for hiding this comment

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

The changes makes sense conceptually.
It's a bit hard to follow the code, so I will take another look later to provide more feedback.

Are there any tests currently testing log formatting is correct?

@clalancette
Copy link
Contributor Author

The changes makes sense conceptually.

👍

It's a bit hard to follow the code, so I will take another look later to provide more feedback.

Yeah, agreed, the diff is especially hard to read. I think it is easier to follow if you look at the complete implementation, but do let me know if there is something I can do to make it easier to read.

Are there any tests currently testing log formatting is correct?

Yeah, there are existing tests in https://github.com/ros2/rcutils/blob/rolling/test/test_logging.cpp , https://github.com/ros2/rcutils/blob/rolling/test/test_logging_macros.cpp , https://github.com/ros2/rcutils/blob/rolling/test/test_logging_long_messages.py , and https://github.com/ros2/rcutils/blob/rolling/test/test_logging_output_format.py . They seemed comprehensive enough, so I didn't add any new ones.

@clalancette
Copy link
Contributor Author

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • Windows Build Status

Copy link
Member

@ivanpauno ivanpauno left a comment

Choose a reason for hiding this comment

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

LGTM!

@ivanpauno
Copy link
Member

Format strings with many, many token substitutions are still
very inefficient. That's because once we go beyond the
fixed 2048 buffer limit and start allocating memory, we only
allocate small chunks of memory at a time. However, this
won't come up in most normal situations (including the default
format message), so we ignore this performance problem for now.

Where's that buffer limit set and where are those small allocations happening?

@ivanpauno
Copy link
Member

Where's that buffer limit set and where are those small allocations happening?

Ah, I see that happens inside rcutils_char_array_t now ...

@ivanpauno
Copy link
Member

Format strings with many, many token substitutions are still
very inefficient. That's because once we go beyond the
fixed 2048 buffer limit and start allocating memory, we only
allocate small chunks of memory at a time. However, this
won't come up in most normal situations (including the default
format message), so we ignore this performance problem for now.

Ah simple way to improve that is to modify rcutils_char_array_expand_as_needed to use a reallocation factor of 1.5.
So the new size is max(1.5*old_size, required_size).
That straregy is widely used AFAIK.

@clalancette
Copy link
Contributor Author

Ah simple way to improve that is to modify rcutils_char_array_expand_as_needed to use a reallocation factor of 1.5. So the new size is max(1.5*old_size, required_size). That straregy is widely used AFAIK.

Yeah, I considered that. I have a couple more minor optimizations that I'll look at doing separately, I'll probably include that as part of it.

@clalancette
Copy link
Contributor Author

CI is green, and approved, so going ahead and merging this. Thanks for the review!

@clalancette clalancette merged commit 2e852fa into rolling Aug 11, 2022
@clalancette clalancette deleted the clalancette/rcutils-logging-format-optimize branch August 11, 2022 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants