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

river/internal/value: change representation of objects and maps #2369

Merged
merged 2 commits into from
Oct 14, 2022

Conversation

rfratto
Copy link
Member

@rfratto rfratto commented Oct 14, 2022

This commit changes the representation of objects and maps from []interface{} and map[string]interface{} to use []value.Value and map[string]value.Value respectively.

This fixes #2362, an issue where interface-based capsule values where losing type information and being coerced to a type based on the actual value backing the interface.

This also greatly improves the performance of creating arrays and objects, which no longer need to be inidividually copied in a loop:

name                   old time/op    new time/op    delta
Object/Non-capsule-10    1.84µs ± 8%    0.00µs ± 0%   -99.89%  (p=0.000 n=19+19)
Object/Capsule-10        1.82µs ± 4%    0.00µs ± 0%   -99.89%  (p=0.000 n=20+19)
Array/Non-capsule-10      389ns ± 2%      19ns ± 2%   -95.20%  (p=0.000 n=19+18)
Array/Capsule-10          389ns ± 1%      19ns ± 0%   -95.19%  (p=0.000 n=20+20)

name                   old alloc/op   new alloc/op   delta
Object/Non-capsule-10    1.88kB ± 0%    0.00kB       -100.00%  (p=0.000 n=20+20)
Object/Capsule-10        1.88kB ± 0%    0.00kB       -100.00%  (p=0.000 n=20+20)
Array/Non-capsule-10       344B ± 0%       24B ± 0%   -93.02%  (p=0.000 n=20+20)
Array/Capsule-10           344B ± 0%       24B ± 0%   -93.02%  (p=0.000 n=20+20)

name                   old allocs/op  new allocs/op  delta
Object/Non-capsule-10      42.0 ± 0%       0.0       -100.00%  (p=0.000 n=20+20)
Object/Capsule-10          42.0 ± 0%       0.0       -100.00%  (p=0.000 n=20+20)
Array/Non-capsule-10       2.00 ± 0%      1.00 ± 0%   -50.00%  (p=0.000 n=20+20)
Array/Capsule-10           2.00 ± 0%      1.00 ± 0%   -50.00%  (p=0.000 n=20+20)

As part of this change, the logic used for the concat function has been greatly simplified. This has seemingly no impact on performance, as the benchmark results below show:

name       old time/op    new time/op    delta
Concat-10    1.10µs ± 4%    1.09µs ± 1%   ~     (p=0.735 n=18+19)

name       old alloc/op   new alloc/op   delta
Concat-10    1.30kB ± 0%    1.30kB ± 0%   ~     (all equal)

name       old allocs/op  new allocs/op  delta
Concat-10      20.0 ± 0%      20.0 ± 0%   ~     (all equal)

I didn't update the CHANGELOG because #2362 only manifested for the otelcol components, which haven't been released yet.

@rfratto rfratto force-pushed the river-capsule-type-loss-fix branch from 720d358 to 199b9f8 Compare October 14, 2022 18:44
Add new benchmarks to test a fix for grafana#2362 and ensure that the
benchmarks for stdlib are using a sufficiently complicated structure
that can benefit from direct assignment.
@rfratto rfratto force-pushed the river-capsule-type-loss-fix branch from 199b9f8 to f8d2640 Compare October 14, 2022 19:00
Copy link
Collaborator

@mattdurham mattdurham left a comment

Choose a reason for hiding this comment

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

This is way simpler and cleaner. A little surprised there are no gotchas but looks great!

@rfratto
Copy link
Member Author

rfratto commented Oct 14, 2022

This is way simpler and cleaner. A little surprised there are no gotchas but looks great!

Yeah, I'm a little nervous that I'm missing something and that something is going to break after this is merged, but we'll see what happens 🤷‍♂️

@rfratto rfratto enabled auto-merge (squash) October 14, 2022 19:07
This commit changes the representation of objects and maps from
[]interface{} and map[string]interface{} to use []value.Value and
map[string]value.Value respectively.

This fixes grafana#2362, an issue where interface-based capsule values where
losing type information and being coerced to a type based on the actual
value.

This also greatly improves the performance of creating arrays and
objects, which no longer need to be inidividually copied in a loop:

```
name                   old time/op    new time/op    delta
Object/Non-capsule-10    1.84µs ± 8%    0.00µs ± 0%   -99.89%  (p=0.000 n=19+19)
Object/Capsule-10        1.82µs ± 4%    0.00µs ± 0%   -99.89%  (p=0.000 n=20+19)
Array/Non-capsule-10      389ns ± 2%      19ns ± 2%   -95.20%  (p=0.000 n=19+18)
Array/Capsule-10          389ns ± 1%      19ns ± 0%   -95.19%  (p=0.000 n=20+20)

name                   old alloc/op   new alloc/op   delta
Object/Non-capsule-10    1.88kB ± 0%    0.00kB       -100.00%  (p=0.000 n=20+20)
Object/Capsule-10        1.88kB ± 0%    0.00kB       -100.00%  (p=0.000 n=20+20)
Array/Non-capsule-10       344B ± 0%       24B ± 0%   -93.02%  (p=0.000 n=20+20)
Array/Capsule-10           344B ± 0%       24B ± 0%   -93.02%  (p=0.000 n=20+20)

name                   old allocs/op  new allocs/op  delta
Object/Non-capsule-10      42.0 ± 0%       0.0       -100.00%  (p=0.000 n=20+20)
Object/Capsule-10          42.0 ± 0%       0.0       -100.00%  (p=0.000 n=20+20)
Array/Non-capsule-10       2.00 ± 0%      1.00 ± 0%   -50.00%  (p=0.000 n=20+20)
Array/Capsule-10           2.00 ± 0%      1.00 ± 0%   -50.00%  (p=0.000 n=20+20)
```

As part of this change, the logic used for the concat function has been
greatly simplified. This has seemingly no impact on performance, as the
benchmark results below show:

```
name       old time/op    new time/op    delta
Concat-10    1.10µs ± 4%    1.09µs ± 1%   ~     (p=0.735 n=18+19)

name       old alloc/op   new alloc/op   delta
Concat-10    1.30kB ± 0%    1.30kB ± 0%   ~     (all equal)

name       old allocs/op  new allocs/op  delta
Concat-10      20.0 ± 0%      20.0 ± 0%   ~     (all equal)
```
@rfratto rfratto force-pushed the river-capsule-type-loss-fix branch from f8d2640 to c76d7ed Compare October 14, 2022 19:11
@rfratto rfratto merged commit 8baa37c into grafana:main Oct 14, 2022
@rfratto rfratto deleted the river-capsule-type-loss-fix branch October 14, 2022 19:21
rfratto added a commit to rfratto/agent that referenced this pull request Oct 26, 2022
… empty objects

This change is similar to the change introduced in grafana#2369, where calling
the `Interface()` method on River values forced a type change from an
interface-based capsule to an any-type capsule.

The new `value.FromRaw` method allows constructing a River value from a
reflect.Value directly, avoiding the need to convert to interface{}.

As part of this change, a `!reflect.Value.IsZero()` check has been added
for safety; this shouldn't happen in most circumstances unless a
value.Null is trying to be encoded.

Fixes grafana#2361.
rfratto added a commit that referenced this pull request Oct 27, 2022
… empty objects (#2437)

This change is similar to the change introduced in #2369, where calling
the `Interface()` method on River values forced a type change from an
interface-based capsule to an any-type capsule.

The new `value.FromRaw` method allows constructing a River value from a
reflect.Value directly, avoiding the need to convert to interface{}.

As part of this change, a `!reflect.Value.IsZero()` check has been added
for safety; this shouldn't happen in most circumstances unless a
value.Null is trying to be encoded.

Fixes #2361.
@github-actions github-actions bot added the frozen-due-to-age Locked due to a period of inactivity. Please open new issues or PRs if more discussion is needed. label Mar 16, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
frozen-due-to-age Locked due to a period of inactivity. Please open new issues or PRs if more discussion is needed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

river: interface-based capsules lose type when put in an array
2 participants