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

Optimize (attribute.Set).Filter for no filtered case #4774

Merged
merged 4 commits into from
Jan 8, 2024

Conversation

MrAlias
Copy link
Contributor

@MrAlias MrAlias commented Dec 20, 2023

When all elements of the Set are kept during a call to (*Set).Filter, don't allocate a new Set the dropped attributes slice. Instead return the immutable Set and nil.

To achieve this the functionality of filterSet is broken down into a more generic filteredToFront function.

Benchmarks

$ benchstat main MrAlias:zero-alloc-unfilterd-set
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/attribute
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
                                          │    old.txt    │               new.txt                │
                                          │    sec/op     │    sec/op     vs base                │
Filtering/NoFilter/Set.Filter-8              2.835n ±  2%   3.085n ±  1%   +8.82% (p=0.000 n=10)
Filtering/NoFilter/NewSetWithFiltered-8      1.563µ ±  7%   1.723µ ± 74%        ~ (p=0.072 n=10)
Filtering/NoFiltered/Set.Filter-8           2906.5n ± 27%   621.9n ±  4%  -78.60% (p=0.000 n=10)
Filtering/NoFiltered/NewSetWithFiltered-8    3.031µ ± 17%   3.231µ ± 33%        ~ (p=0.796 n=10)
Filtering/Filtered/Set.Filter-8              2.404µ ± 12%   2.240µ ± 17%        ~ (p=0.579 n=10)
Filtering/Filtered/NewSetWithFiltered-8      1.291µ ±  2%   1.276µ ±  2%   -1.16% (p=0.037 n=10)
Filtering/AllDropped/Set.Filter-8            2.111µ ± 37%   2.441µ ± 11%        ~ (p=0.190 n=10)
Filtering/AllDropped/NewSetWithFiltered-8    752.7n ±  3%   758.8n ±  3%        ~ (p=0.853 n=10)
geomean                                      813.8n         698.3n        -14.20%

                                          │    old.txt     │                  new.txt                  │
                                          │      B/op      │     B/op      vs base                     │
Filtering/NoFilter/Set.Filter-8               0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=10) ¹
Filtering/NoFilter/NewSetWithFiltered-8     3.501Ki ± 0%     3.501Ki ± 0%         ~ (p=1.000 n=10) ¹
Filtering/NoFiltered/Set.Filter-8           5.250Ki ± 0%     0.000Ki ± 0%  -100.00% (p=0.000 n=10)
Filtering/NoFiltered/NewSetWithFiltered-8   3.501Ki ± 0%     3.501Ki ± 0%         ~ (p=1.000 n=10) ¹
Filtering/Filtered/Set.Filter-8             1.812Ki ± 0%     1.812Ki ± 0%         ~ (p=1.000 n=10) ¹
Filtering/Filtered/NewSetWithFiltered-8       64.00 ± 0%       64.00 ± 0%         ~ (p=1.000 n=10) ¹
Filtering/AllDropped/Set.Filter-8           1.750Ki ± 0%     1.750Ki ± 0%         ~ (p=1.000 n=10) ¹
Filtering/AllDropped/NewSetWithFiltered-8     0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=10) ¹
geomean                                                  ²                 ?                       ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

                                          │   old.txt    │                 new.txt                 │
                                          │  allocs/op   │ allocs/op   vs base                     │
Filtering/NoFilter/Set.Filter-8             0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
Filtering/NoFilter/NewSetWithFiltered-8     2.000 ± 0%     2.000 ± 0%         ~ (p=1.000 n=10) ¹
Filtering/NoFiltered/Set.Filter-8           3.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
Filtering/NoFiltered/NewSetWithFiltered-8   2.000 ± 0%     2.000 ± 0%         ~ (p=1.000 n=10) ¹
Filtering/Filtered/Set.Filter-8             2.000 ± 0%     2.000 ± 0%         ~ (p=1.000 n=10) ¹
Filtering/Filtered/NewSetWithFiltered-8     1.000 ± 0%     1.000 ± 0%         ~ (p=1.000 n=10) ¹
Filtering/AllDropped/Set.Filter-8           1.000 ± 0%     1.000 ± 0%         ~ (p=1.000 n=10) ¹
Filtering/AllDropped/NewSetWithFiltered-8   0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
geomean                                                ²               ?                       ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

Copy link

codecov bot commented Dec 20, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (133f943) 82.2% compared to head (7c84fa5) 82.3%.

❗ Current head 7c84fa5 differs from pull request most recent head c2152dc. Consider uploading reports for the commit c2152dc to get more accurate results

Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##            main   #4774   +/-   ##
=====================================
  Coverage   82.2%   82.3%           
=====================================
  Files        226     226           
  Lines      18381   18392   +11     
=====================================
+ Hits       15127   15148   +21     
+ Misses      2972    2963    -9     
+ Partials     282     281    -1     
Files Coverage Δ
attribute/set.go 80.4% <100.0%> (+2.6%) ⬆️

... and 1 file with indirect coverage changes

@MrAlias MrAlias changed the title Optimize attribute.Set filtering Optimize (attribute.Set).Filter for no filtered case Jan 2, 2024
@MrAlias MrAlias force-pushed the zero-alloc-unfilterd-set branch 2 times, most recently from 892162f to 42d644b Compare January 3, 2024 16:20
When all elements of the Set are kept during a call to Filter, do not
allocate a new Set and the dropped attributes slice. Instead, return the
immutable Set and nil.

To achieve this the functionality of filterSet is broken down into a
more generic filteredToFront function.
@MrAlias MrAlias force-pushed the zero-alloc-unfilterd-set branch from a9ae4f3 to c0a178b Compare January 3, 2024 16:29
@MrAlias MrAlias added the pkg:attribute Related to the attribute package label Jan 3, 2024
@MrAlias MrAlias marked this pull request as ready for review January 3, 2024 16:32
CHANGELOG.md Outdated Show resolved Hide resolved
attribute/set.go Outdated Show resolved Hide resolved
attribute/set.go Show resolved Hide resolved
attribute/set_test.go Outdated Show resolved Hide resolved
MrAlias and others added 2 commits January 3, 2024 09:06
@MrAlias MrAlias merged commit deddec3 into open-telemetry:main Jan 8, 2024
23 checks passed
@MrAlias MrAlias deleted the zero-alloc-unfilterd-set branch January 8, 2024 15:49
@MrAlias MrAlias added this to the v1.22.0 milestone Jan 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg:attribute Related to the attribute package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants