boostorg / boostorg/accumulators

`accumulator_set` has surprisingly large padding overhead

Open
#68 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
26
Forks
61
PR merge metrics
No merged PRs in 30d

Description

I was double checking that `accumulator_set` is essentially a zero-cost abstraction — But I was surprised to find that's not quite the case!

```cpp
accumulator_set> acc;
struct HandRolled { std::size_t count; double sum; double sum_sq; };
static_assert(sizeof(HandRolled) == 24);
static_assert(sizeof(acc) == 40); // 66% overhead!!!
```

I think the overhead comes from the fusion cons list `fusion::cons>>`. Each of the child elements is a full object, so the compiler can't optimize out empty types:

```cpp
// boost/fusion/container/list/cons.hpp:142-143
car_type car;
cdr_type cdr;
```

| impl | stores | cost after padding in cons |
|--- |--- |--- |
| `count_impl` | `size_t` | 8 |
| `sum_impl` | `double` | 8 |
| `moment<2>_impl` | `double` | 8 |
| `mean_impl` | | **8** |
| `lazy_variance_impl` | | **8** |

I honestly hoped I could attempt a two line fix in `cons.hpp`:

```diff
- car_type car;
- cdr_type cdr;
+ BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS car_type car;
+ BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS cdr_type cdr;
```

I hotpatched `/usr/include/boost/fusion/container/list/cons.hpp`, but I couldn't observe any actual memory savings with this on clang or gcc.

Environment

- Boost 1.89.0
- GCC 15.2 / Clang 19
- x86-64 Linux (Arch)

Is this problem worth solving? If I spent longer on this to try and filter out empty types eg. `mean_impl` `lazy_variance_impl` at compile time, would this PR be accepted?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.