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: store/cachekv: preallocate kvL in dirtyItems which gets appended too #14168

Merged
merged 2 commits into from
Dec 7, 2022

Conversation

odeke-em
Copy link
Collaborator

@odeke-em odeke-em commented Dec 6, 2022

Noticed in RAM profiles that the append for kvL had a concentrated amount of RAM consumption yet where we invoke make didn't have any capacity. Alas on profiling the results show a distribution which eases on allocation pressure and distributes allocations across different sections:

  • Before:
         .          .    342:	kvL := make([]*kv.Pair, 0)
         .          .    343:	for i := startIndex; i <= endIndex; i++ {
         .          .    344:		key := strL[i]
         .          .    345:		cacheValue := store.cache[key]
    1.14GB     1.14GB    346:		kvL = append(kvL, &kv.Pair{Key: []byte(key), Value: cacheValue.value})
         .          .    347:	}
  • After:
   76.33MB    76.33MB    342:	kvL := make([]*kv.Pair, 0, endIndex-startIndex)
         .          .    343:	for i := startIndex; i <= endIndex; i++ {
         .          .    344:		key := strL[i]
         .          .    345:		cacheValue := store.cache[key]
  851.42MB   851.42MB    346:		kvL = append(kvL, &kv.Pair{Key: []byte(key), Value: cacheValue.value})
         .          .    347:	}

which also shows up in benchmark results:

$ benchstat before.txt after.txt
name                             old time/op    new time/op    delta
IteratorOnParentWith1MDeletes-8     1.69s ± 5%     1.65s ± 6%    ~     (p=0.095 n=9+10)

name                             old alloc/op   new alloc/op   delta
IteratorOnParentWith1MDeletes-8     238MB ± 0%     214MB ± 0%  -9.94%  (p=0.000 n=10+9)

name                             old allocs/op  new allocs/op  delta
IteratorOnParentWith1MDeletes-8     3.10M ± 0%     3.10M ± 0%  -0.00%  (p=0.000 n=10+10)

Fixes #14167

@odeke-em odeke-em requested a review from a team as a code owner December 6, 2022 04:35
@odeke-em odeke-em requested a review from ValarDragon December 6, 2022 04:35
store/cachekv/store.go Outdated Show resolved Hide resolved
Copy link
Member

@tac0turtle tac0turtle left a comment

Choose a reason for hiding this comment

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

makes sense

…d too

Noticed in RAM profiles that the append for kvL had a concentrated
amount of RAM consumption yet where we invoke make didn't have any
capacity. Alas on profiling the results show a distribution which
eases on allocation pressure and distributes allocations across
different sections:

* Before:
```shell
         .          .    342:	kvL := make([]*kv.Pair, 0)
         .          .    343:	for i := startIndex; i <= endIndex; i++ {
         .          .    344:		key := strL[i]
         .          .    345:		cacheValue := store.cache[key]
    1.14GB     1.14GB    346:		kvL = append(kvL, &kv.Pair{Key: []byte(key), Value: cacheValue.value})
         .          .    347:	}
```

* After:
```shell
   76.33MB    76.33MB    342:	kvL := make([]*kv.Pair, 0, endIndex-startIndex)
         .          .    343:	for i := startIndex; i <= endIndex; i++ {
         .          .    344:		key := strL[i]
         .          .    345:		cacheValue := store.cache[key]
  851.42MB   851.42MB    346:		kvL = append(kvL, &kv.Pair{Key: []byte(key), Value: cacheValue.value})
         .          .    347:	}
```

which also shows up in benchmark results:

```shell
$ benchstat before.txt after.txt
name                             old time/op    new time/op    delta
IteratorOnParentWith1MDeletes-8     1.69s ± 5%     1.65s ± 6%    ~     (p=0.095 n=9+10)

name                             old alloc/op   new alloc/op   delta
IteratorOnParentWith1MDeletes-8     238MB ± 0%     214MB ± 0%  -9.94%  (p=0.000 n=10+9)

name                             old allocs/op  new allocs/op  delta
IteratorOnParentWith1MDeletes-8     3.10M ± 0%     3.10M ± 0%  -0.00%  (p=0.000 n=10+10)
```

Fixes #14167
@odeke-em odeke-em force-pushed the store-cachekv-store-preallocate-kvL-in-dirtyItems branch from 32dbd02 to 1a14565 Compare December 6, 2022 22:08
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 6, 2022

[Cosmos SDK] Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

100.0% 100.0% Coverage
0.0% 0.0% Duplication

@tac0turtle tac0turtle enabled auto-merge (squash) December 7, 2022 08:39
@tac0turtle tac0turtle added the A:automerge Automatically merge PR once all prerequisites pass. label Dec 7, 2022
@tac0turtle tac0turtle merged commit 0115f88 into main Dec 7, 2022
@tac0turtle tac0turtle deleted the store-cachekv-store-preallocate-kvL-in-dirtyItems branch December 7, 2022 09:00
BrandonWeng added a commit to sei-protocol/sei-cosmos that referenced this pull request Dec 15, 2022
## Describe your changes and provide context
Cherry picking changes here:
* [\#14168](cosmos/cosmos-sdk#14168) perf:
store/cachekv: preallocate kvL in dirtyItems which gets appended too
* [\#10024](cosmos/cosmos-sdk#10024) fix!:
store/cachekv: reduce growth factor for iterator ranging using binary
searches #10024

## Testing performed to validate your change
Ran a cluster

![image](https://user-images.githubusercontent.com/18161326/207636380-1c404827-cdb4-4bdc-aade-bfc0294f6cd4.png)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A:automerge Automatically merge PR once all prerequisites pass. C:Store
Projects
None yet
3 participants