Skip to content

Optimize C++ generated code for structures with many conditional fields#241

Open
AaronWebster wants to merge 7 commits intomasterfrom
optimized-conditionals-v3
Open

Optimize C++ generated code for structures with many conditional fields#241
AaronWebster wants to merge 7 commits intomasterfrom
optimized-conditionals-v3

Conversation

@AaronWebster
Copy link
Collaborator

@AaronWebster AaronWebster commented Jan 29, 2026

This change improves the performance of the generated C++ code for Emboss structures containing many conditional fields.

Specifically, it optimizes the validation logic (e.g., the Ok() method) and field access patterns where fields depend on a shared discriminant or tag. This results in faster runtime validation and reduced overhead when interacting with complex structures defined with extensive conditional logic.

Performance Impact

Benchmarked on testdata/many_conditionals.emb with 10,000 iterations x 100 tags, compiled with -c opt:

Metric Master PR Improvement
Compiled Binary Text Section 64,519 bytes 30,079 bytes 53.4% reduction
Runtime (avg of 3 runs) ~1.31s ~0.11s 11.8x faster
Header File Size 611,751 bytes 612,180 bytes +429 bytes (+0.07%)

Summary

  • Runtime Speedup: 11.8x (from ~1.31s to ~0.11s)
  • Binary Size Reduction: 53.4% (text section reduced from 64.5KB to 30KB, saving ~34KB)
  • Header source size is essentially unchanged (trivial 0.07% increase)

Recreated from #235 after the source branch was deleted.

AaronWebster and others added 6 commits December 2, 2025 15:27
- Remove [[nodiscard]] annotations (C++17 feature) and create separate
  issue #242 to discuss C++14 vs C++17 support
- Remove redundant check in ExpressionScope.add() that was already
  covered by the parent scope lookup
- Revert unnecessary style change in _render_existence_test
- Add comprehensive docstring to _generate_optimized_ok_method_body
  explaining the switch optimization with examples
- Refactor switch/if generation to use templates for better readability
- Optimize trivially-true conditions to skip if-block wrapper when
  condition is statically known to be true
Regenerate all golden .emb.h files to reflect changes from the
optimized conditionals implementation.
@AaronWebster AaronWebster requested a review from EricRahm January 29, 2026 19:08
@AaronWebster AaronWebster self-assigned this Jan 29, 2026
@AaronWebster AaronWebster added the optimization Performance improvements that do not otherwise change behavior label Jan 29, 2026
Add golden file and test for many_conditionals.emb to ensure
the generated C++ header is tracked for review.
Copy link
Collaborator

@EricRahm EricRahm left a comment

Choose a reason for hiding this comment

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

Thanks for polishing this up! Looks really good, added some high level comments. I think overall it'd be a little easier to review if we split out the always true optimization.

both guarded by tag == 0), only the first field for that case value is
checked in the switch. This is because once we've checked var_0 for case 0,
we break out of the switch. Fields with duplicate case values will fall
through to the if-statement path.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Overall great comment, I really appreciate the clear explanations. Sorry to harp on this, but can you add a test case to make sure the statements here match up with the code behavior?

I suspect this will lead to a bit more churn so I'll hold off on digging to much deeper.

emb_file,
golden_file,
include_dirs=None,
compiler_flags=None,
Copy link
Collaborator

Choose a reason for hiding this comment

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

The one_golden_test and run_one_golden_test changes seem like they might be a separate issue? If so would you mind splitting that out (and we can land it quickly).


This module contains types used by the LR(1) parser, which are also used in
other parts of the compiler:
other parts of the compiler:
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: this seems unrelated

and group["expr"].type.boolean.value
)

if is_always_true:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I love this change! I wonder if we could split it out out as a separate issue, I think it'd make the golden churn a little bit easier to grok and also highlight the impact of it :)

const auto emboss_reserved_local_ok_subexpr_23 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_ok_subexpr_19, emboss_reserved_local_ok_subexpr_22);
const auto emboss_reserved_local_ok_subexpr_24 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_ok_subexpr_10, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
const auto emboss_reserved_local_ok_subexpr_25 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_ok_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
const auto emboss_reserved_local_ok_subexpr_26 = ::emboss::support::Or</**/bool, bool, bool, bool>(emboss_reserved_local_ok_subexpr_24, emboss_reserved_local_ok_subexpr_25);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This feels like somehow this got worse, maybe the tradeoff is worth it but I wonder if we could do better.

VALUE = static_cast</**/::std::int32_t>(10LL),

};
template <class Enum>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suspect this is a result of the fix for passing in compiler args in the one_golden_test changes?

@@ -1,13 +0,0 @@
# Copyright 2019 Google LLC
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think we want to delete this?

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

Labels

optimization Performance improvements that do not otherwise change behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants