Skip to content

Buffer size used in writeDelimitedTo method is often too small #4177

Closed

Description

@pstibrany

When sending small messages (e.g. message consisting of single enum) by using AbstractMessageLite#writeDelimitedTo method, this method together with CodedOutputStream will compute very small buffer size of 20.

AbstractMessageLite#writeDelimitedTo then writes single byte (message size) to the buffer, not leaving enough space for CodedOutputStream.writeEnum method, which always wants at least 20 available bytes, and which then must flush that single byte (message size) to make enough room to write enums.

This interplay between AbstractMessageLite#writeDelimitedTo and CodedOutputStream, which needs more free space in the buffer now for many types, causes lot of unnecessary writes to the output stream (which is bad especially when using SocketOutputStream).

We have observed this as a major performance hit when upgrading from protobuf 2.5.0 to version 3.

For a simple test case, please see https://github.com/pstibrany/protobuf-small-buffer-issue

Activity

  1. pstibrany commented on Jan 17, 2018

    @pstibrany
    Author

    Small message is just an example, problem can of course be observed for bigger messages as well. CodedOutputStream now simply needs more space in the buffer to avoid flushing, than what AbstractMessageLite#writeDelimitedTo provides.

  2. Repository owner unassigned on Jul 19, 2019
  3. self-assigned this
    on Mar 1, 2022
  4. elharo commented on Mar 4, 2022

    @elharo
    Contributor

    The big question here is, as with all optimizations, does it matter? That is, suppose AbstractMessageLite#writeDelimitedTo is ten times slower. Does this have any noticeable impact on the performance of anything? E.g. does an app take five seconds longer to start up? Does a batch job complete in a day instead of an hour? Or does a BigQuery cost twice as much to run? Can any significant impact be shown that justifies the effort of improving this?

    Any evidence you have along these lines would be helpful.

  5. pstibrany commented on Mar 4, 2022

    @pstibrany
    Author

    The big question here is, as with all optimizations, does it matter?

    We definitely noticed it on our system ("We have observed this as a major performance hit when upgrading from protobuf 2.5.0 to version 3."), when I investigated this. Unfortunately that was 4 years ago, and I don't remember or work on the same system anymore (I don't have access to it), so I cannot provide more details.

  6. elharo commented on Mar 4, 2022

    @elharo
    Contributor

    Confirmed this still exists as of 3.19.4:

     [java] Serialized size: 2, writes: 2
     [java] Serialized size: 9, writes: 2
     [java] Serialized size: 11, writes: 3
    
  7. removed their assignment
    on Jul 8, 2022
  8. github-actions commented on Jun 9, 2024

    @github-actions

    We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please add a comment.

    This issue is labeled inactive because the last activity was over 90 days ago.

  9. added
    inactiveDenotes the issue/PR has not seen activity in the last 90 days.
    on Jun 9, 2024
  10. pstibrany commented on Jun 10, 2024

    @pstibrany
    Author

    I'm fine to close this. I don't have any interest in this issue any more, and it seems that nobody else suffers from this either.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    inactiveDenotes the issue/PR has not seen activity in the last 90 days.javaperformance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions