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

perf: optimize memory usage for client.List func #369

Merged
merged 2 commits into from
Jan 2, 2024

Conversation

halfcrazy
Copy link
Contributor

@halfcrazy halfcrazy commented Oct 7, 2023

Fix #367
If there is a predicate condition, we should not alloc a very large slice

goos: linux
goarch: amd64
pkg: github.com/ovn-org/libovsdb/client
cpu: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
                                                            │ bench.out.main │            bench.out.new             │
                                                            │     sec/op     │    sec/op     vs base                │
APIList/predicate_returns_none-4                                3.419m ± 41%   3.238m ±  1%   -5.29% (p=0.001 n=10)
APIList/predicate_returns_all-4                                 67.92m ±  3%   68.95m ±  1%        ~ (p=0.123 n=10)
APIList/predicate_on_an_arbitrary_condition-4                   11.88m ±  2%   12.10m ± 11%        ~ (p=0.075 n=10)
APIList/predicate_matches_name-4                                4.073m ±  4%   5.006m ± 17%  +22.91% (p=0.000 n=10)
APIList/by_index,_no_predicate-4                               32.644µ ±  4%   7.957µ ±  3%  -75.62% (p=0.000 n=10)
APIListMultiple/multiple_results_one_at_a_time_with_Get-4       6.073m ±  4%   6.021m ± 11%        ~ (p=0.853 n=10)
APIListMultiple/multiple_results_in_a_batch_with_WhereAny-4     3.014m ±  2%   3.085m ± 19%   +2.36% (p=0.002 n=10)
geomean                                                         3.521m         2.962m        -15.89%

                                                            │ bench.out.main │            bench.out.new             │
                                                            │      B/op      │     B/op      vs base                │
APIList/predicate_returns_none-4                                908.6Ki ± 0%   828.6Ki ± 0%   -8.80% (p=0.000 n=10)
APIList/predicate_returns_all-4                                 14.88Mi ± 0%   14.88Mi ± 0%        ~ (p=0.315 n=10)
APIList/predicate_on_an_arbitrary_condition-4                   2.468Mi ± 0%   2.399Mi ± 0%   -2.80% (p=0.000 n=10)
APIList/predicate_matches_name-4                                910.3Ki ± 0%   830.3Ki ± 0%   -8.79% (p=0.000 n=10)
APIList/by_index,_no_predicate-4                               81.997Ki ± 0%   2.000Ki ± 0%  -97.56% (p=0.000 n=10)
APIListMultiple/multiple_results_one_at_a_time_with_Get-4       1.439Mi ± 0%   1.439Mi ± 0%        ~ (p=0.197 n=10)
APIListMultiple/multiple_results_in_a_batch_with_WhereAny-4     712.7Ki ± 0%   712.7Ki ± 0%        ~ (p=0.280 n=10)
geomean                                                         1.128Mi        659.2Ki       -42.93%

                                                            │ bench.out.main │            bench.out.new             │
                                                            │   allocs/op    │  allocs/op   vs base                 │
APIList/predicate_returns_none-4                                 20.01k ± 0%   20.01k ± 0%  -0.00% (p=0.000 n=10)
APIList/predicate_returns_all-4                                  230.1k ± 0%   230.1k ± 0%  +0.00% (p=0.048 n=10)
APIList/predicate_on_an_arbitrary_condition-4                    43.36k ± 0%   43.36k ± 0%       ~ (p=1.000 n=10)
APIList/predicate_matches_name-4                                 20.03k ± 0%   20.03k ± 0%       ~ (p=1.000 n=10) ¹
APIList/by_index,_no_predicate-4                                  32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=10) ¹
APIListMultiple/multiple_results_one_at_a_time_with_Get-4        22.02k ± 0%   22.01k ± 0%       ~ (p=0.170 n=10)
APIListMultiple/multiple_results_in_a_batch_with_WhereAny-4      11.51k ± 0%   11.51k ± 0%       ~ (p=1.000 n=10) ¹
geomean                                                          11.83k        11.83k       -0.00%
¹ all samples are equal

main
image
perf
image

If there is a predicate condition, we should not alloc a very large
slice

```
goos: linux
goarch: amd64
pkg: github.com/ovn-org/libovsdb/client
cpu: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
                                                            │ bench.out.main │            bench.out.new             │
                                                            │     sec/op     │    sec/op     vs base                │
APIList/predicate_returns_none-4                                3.419m ± 41%   3.238m ±  1%   -5.29% (p=0.001 n=10)
APIList/predicate_returns_all-4                                 67.92m ±  3%   68.95m ±  1%        ~ (p=0.123 n=10)
APIList/predicate_on_an_arbitrary_condition-4                   11.88m ±  2%   12.10m ± 11%        ~ (p=0.075 n=10)
APIList/predicate_matches_name-4                                4.073m ±  4%   5.006m ± 17%  +22.91% (p=0.000 n=10)
APIList/by_index,_no_predicate-4                               32.644µ ±  4%   7.957µ ±  3%  -75.62% (p=0.000 n=10)
APIListMultiple/multiple_results_one_at_a_time_with_Get-4       6.073m ±  4%   6.021m ± 11%        ~ (p=0.853 n=10)
APIListMultiple/multiple_results_in_a_batch_with_WhereAny-4     3.014m ±  2%   3.085m ± 19%   +2.36% (p=0.002 n=10)
geomean                                                         3.521m         2.962m        -15.89%

                                                            │ bench.out.main │            bench.out.new             │
                                                            │      B/op      │     B/op      vs base                │
APIList/predicate_returns_none-4                                908.6Ki ± 0%   828.6Ki ± 0%   -8.80% (p=0.000 n=10)
APIList/predicate_returns_all-4                                 14.88Mi ± 0%   14.88Mi ± 0%        ~ (p=0.315 n=10)
APIList/predicate_on_an_arbitrary_condition-4                   2.468Mi ± 0%   2.399Mi ± 0%   -2.80% (p=0.000 n=10)
APIList/predicate_matches_name-4                                910.3Ki ± 0%   830.3Ki ± 0%   -8.79% (p=0.000 n=10)
APIList/by_index,_no_predicate-4                               81.997Ki ± 0%   2.000Ki ± 0%  -97.56% (p=0.000 n=10)
APIListMultiple/multiple_results_one_at_a_time_with_Get-4       1.439Mi ± 0%   1.439Mi ± 0%        ~ (p=0.197 n=10)
APIListMultiple/multiple_results_in_a_batch_with_WhereAny-4     712.7Ki ± 0%   712.7Ki ± 0%        ~ (p=0.280 n=10)
geomean                                                         1.128Mi        659.2Ki       -42.93%

                                                            │ bench.out.main │            bench.out.new             │
                                                            │   allocs/op    │  allocs/op   vs base                 │
APIList/predicate_returns_none-4                                 20.01k ± 0%   20.01k ± 0%  -0.00% (p=0.000 n=10)
APIList/predicate_returns_all-4                                  230.1k ± 0%   230.1k ± 0%  +0.00% (p=0.048 n=10)
APIList/predicate_on_an_arbitrary_condition-4                    43.36k ± 0%   43.36k ± 0%       ~ (p=1.000 n=10)
APIList/predicate_matches_name-4                                 20.03k ± 0%   20.03k ± 0%       ~ (p=1.000 n=10) ¹
APIList/by_index,_no_predicate-4                                  32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=10) ¹
APIListMultiple/multiple_results_one_at_a_time_with_Get-4        22.02k ± 0%   22.01k ± 0%       ~ (p=0.170 n=10)
APIListMultiple/multiple_results_in_a_batch_with_WhereAny-4      11.51k ± 0%   11.51k ± 0%       ~ (p=1.000 n=10) ¹
geomean                                                          11.83k        11.83k       -0.00%
¹ all samples are equal
```

Signed-off-by: Yan Zhu <[email protected]>
@halfcrazy
Copy link
Contributor Author

ping

@halfcrazy
Copy link
Contributor Author

ping @jcaamano

client/api.go Outdated
Comment on lines 156 to 173
if resultVal.IsNil() || resultVal.Cap() == 0 {
resultVal.Set(reflect.MakeSlice(resultVal.Type(), 0, len(rows)))
}
} else {
rows = tableCache.Rows()
// If given a null slice, fill it in the cache table completely, if not, just up to
// its capability.
if resultVal.IsNil() || resultVal.Cap() == 0 {
resultVal.Set(reflect.MakeSlice(resultVal.Type(), 0, tableCache.Len()))
}
}
i := resultVal.Len()
maxCap := resultVal.Cap()

for _, row := range rows {
if i >= resultVal.Cap() {
if i >= maxCap {
break
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

@halfcrazy sorry this took so long. Would this work:

	var rows map[string]model.Model
	if a.cond != nil {
		rows, err = a.cond.Matches()
		if err != nil {
			return err
		}
	} else {
		rows = tableCache.Rows()
	}
	
	// If given a null slice, fill it in with all the resulting rows, if not, just up to
	// its capacity.
	if resultVal.IsNil() || resultVal.Cap() == 0 {
		resultVal.Set(reflect.MakeSlice(resultVal.Type(), 0, len(rows)))
	}
	i := resultVal.Len()
	cap := resultVal.Cap()
	for _, row := range rows {
		if i >= cap {
			break
		}
		...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

update

Signed-off-by: Yan Zhu <[email protected]>
@jcaamano jcaamano merged commit c71cb09 into ovn-org:main Jan 2, 2024
7 checks passed
@coveralls
Copy link

Pull Request Test Coverage Report for Build 6441536993

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 8 of 8 (100.0%) changed or added relevant lines in 1 file are covered.
  • 60 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.003%) to 75.982%

Files with Coverage Reduction New Missed Lines %
client/client.go 2 73.78%
client/api.go 58 82.89%
Totals Coverage Status
Change from base Build 6159565928: 0.003%
Covered Lines: 5302
Relevant Lines: 6978

💛 - Coveralls

1 similar comment
@coveralls
Copy link

coveralls commented Mar 31, 2024

Pull Request Test Coverage Report for Build 6441536993

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 8 of 8 (100.0%) changed or added relevant lines in 1 file are covered.
  • 60 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.003%) to 75.982%

Files with Coverage Reduction New Missed Lines %
client/client.go 2 73.78%
client/api.go 58 82.89%
Totals Coverage Status
Change from base Build 6159565928: 0.003%
Covered Lines: 5302
Relevant Lines: 6978

💛 - Coveralls

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.

client: Improve List memory usage
3 participants