Skip to content

Perf[BMQ,MQB]: simplify evaluator - #837

Merged
678098 merged 5 commits into
bloomberg:mainfrom
678098:250717_simplify_evaluator
Aug 11, 2025
Merged

678098 merged 5 commits into
bloomberg:mainfrom
678098:250717_simplify_evaluator

Conversation

@678098

@678098 678098 commented Jul 17, 2025 •

Copy link
Copy Markdown
Contributor

Changes

  1. bmqeval::EvaluationContext: get rid of the bool flag d_stop and use d_lastError to exit evaluation early. This also speeds up the reset of evaluation context. The idea is that if we have an error stored in the field already we must stop early, and we don't need a special bool flag for this.
  2. mqbblp::Routers: remove unnecessary check if (!d_evaluator.isCompiled()). The same behaviour can be achieved by only checking d_evaluator.isValid(). Look at the table in the comments that explains return values of bool Routers::Expression::evaluate().
  3. mqbblp::Routers: remove unnecessary check if (d_evaluationContext_p->hasError()). The same can be checked in evaluator itself.
  4. Remove mutable int bmqp::MessageProperties::d_lastError
  5. bmqp::MessageProperties::Property: reorder fields and put bdlb::Variant7 in the beginning to improve field packing and alignment. sizeof of this structure reduced from 88 bytes to 80. This struct has to be aligned by 16 byte offset, so the old version used 96 bytes if places continuously in memory, now these structures can be placed in memory without gaps because 80 = 16*5.
  6. bmqp::MessageProperties::findProperty: do not construct next property on stack if not needed.

@678098
678098 requested a review from a team as a code owner July 17, 2025 18:10
if (context.d_stop) {
if (context.hasError()) {
return false; // RETURN
}

@678098 678098 Jul 17, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This ensures the same behaviour as the code that was removed from mqbblp::Routers without adding extra performance cost:

        if (d_evaluationContext_p->hasError()) {
            return false;  // RETURN
        }

@678098
678098 requested a review from dorjesinpo July 17, 2025 18:17
@678098
678098 force-pushed the 250717_simplify_evaluator branch 3 times, most recently from ee0a853 to bcd2182 Compare July 17, 2025 19:15
@678098 678098 changed the title Perf[BMQEVAL,MQBBLP]: simplify evaluator Perf[BMQ,MQB]: simplify evaluator Jul 17, 2025
Comment thread src/groups/bmq/bmqp/bmqp_messageproperties.h

@bmq-oss-ci bmq-oss-ci Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Build 2910 of commit 2ce29fe has completed with FAILURE

/// Rb-tree containing property name->value pairs.
/// Note: when the number of properties is small map works faster than
/// unordered_map. Also, map takes less space.
mutable PropertyMap d_properties;

@678098 678098 Jul 18, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

typedef bsl::map<bsl::string, Property> PropertyMap;

  1. This is a map, not unordered_map.
  2. I tried switching it to unordered_map, and it works much slower than map when we only have 1-2 properties. String hashing takes a lot of time in such cases.

The same benchmark, this function takes 4% of CPU frames when map is used:

4.08% BloombergLP::bmqp::MessageProperties::findProperty

If we switch it to unordered_map, it uses 9% of CPU frames and mostly it is string hashing.

@bmq-oss-ci bmq-oss-ci Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Build 2912 of commit f0d2f66 has completed with FAILURE


if (left.theBoolean()) {
return bdld::Datum::createBoolean(true); // RETURN
return left; // RETURN

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the return type is not const, are we sure we can use the same instance?
(wee seem to be ok returning right)

@678098 678098 Aug 6, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We keep left by value, not by reference. We also return it by value. Datum is a simply copyable type, so value copy is safe.

There is no need to construct another Datum if we can simply return left that 1)owned by the local scope 2)is already constructed 3)has the correct true value.


// Set by `Expression::evaluate` functions when a property does not
// have the type deduced during compilation. Stop evaluation and return
// `true`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

was the comment wrong and we return false?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The comment was wrong indeed. That is the problem with comments describing implementation in a distant part of the code.

Comment thread src/groups/bmq/bmqp/bmqp_messageproperties.h
/// | false | true | IMPOSSIBLE |
/// | true | false | true |
/// | true | true | d_evaluator.evaluate() |
/// |============|=========|========================|

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thank you for documenting this. we could also document the result when a property is missing

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a comment below

@678098
678098 force-pushed the 250717_simplify_evaluator branch 3 times, most recently from 3c24e82 to ecfe28a Compare August 6, 2025 13:20
@678098
678098 requested a review from dorjesinpo August 6, 2025 13:33
678098 added 5 commits August 11, 2025 18:04
Signed-off-by: Evgeny Malygin <emalygin@bloomberg.net>
Signed-off-by: Evgeny Malygin <emalygin@bloomberg.net>
Signed-off-by: Evgeny Malygin <emalygin@bloomberg.net>
Signed-off-by: Evgeny Malygin <emalygin@bloomberg.net>
Signed-off-by: Evgeny Malygin <emalygin@bloomberg.net>
@678098
678098 force-pushed the 250717_simplify_evaluator branch from ecfe28a to 0379b1b Compare August 11, 2025 17:04

@dorjesinpo dorjesinpo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thank you

@678098
678098 merged commit 3128eb3 into bloomberg:main Aug 11, 2025
@678098
678098 deleted the 250717_simplify_evaluator branch August 11, 2025 17:33
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