Refactor sign/verify message #8

Merged
fyrchik merged 1 commit from dstepanov-yadro/frostfs-api-go:feat/refactor-signservicemessage into master 2023-07-26 21:08:03 +00:00
  1. Code refactor: drop some wrappers, split methods to different files, extract methods
  2. Do signing/verification parallel
  3. Use buffers for slices
benchstat master.bench pool.bench
goos: linux
goarch: amd64
pkg: github.com/TrueCloudLab/frostfs-api-go/v2/signature
cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
                │ master.bench │              pool.bench               │
                │    sec/op    │    sec/op     vs base                 │
SignRequest-8     98.15µ ± ∞ ¹   54.78µ ± ∞ ¹        ~ (p=1.000 n=1) ²
VerifyRequest-8   300.3µ ± ∞ ¹   148.7µ ± ∞ ¹        ~ (p=1.000 n=1) ²
geomean           171.7µ         90.25µ        -47.43%
¹ need >= 6 samples for confidence interval at level 0.95
² need >= 4 samples to detect a difference at alpha level 0.05

                │ master.bench  │              pool.bench               │
                │     B/op      │     B/op       vs base                │
SignRequest-8     15.03Ki ± ∞ ¹   15.20Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
VerifyRequest-8   11.02Ki ± ∞ ¹   10.87Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
geomean           12.87Ki         12.85Ki        -0.12%
¹ need >= 6 samples for confidence interval at level 0.95
² need >= 4 samples to detect a difference at alpha level 0.05

                │ master.bench │             pool.bench              │
                │  allocs/op   │  allocs/op   vs base                │
SignRequest-8      158.0 ± ∞ ¹   159.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
VerifyRequest-8    129.0 ± ∞ ¹   130.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
geomean            142.8         143.8        +0.70%
¹ need >= 6 samples for confidence interval at level 0.95
² need >= 4 samples to detect a difference at alpha level 0.05
1. Code refactor: drop some wrappers, split methods to different files, extract methods 2. Do signing/verification parallel 3. Use buffers for slices ``` benchstat master.bench pool.bench goos: linux goarch: amd64 pkg: github.com/TrueCloudLab/frostfs-api-go/v2/signature cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz │ master.bench │ pool.bench │ │ sec/op │ sec/op vs base │ SignRequest-8 98.15µ ± ∞ ¹ 54.78µ ± ∞ ¹ ~ (p=1.000 n=1) ² VerifyRequest-8 300.3µ ± ∞ ¹ 148.7µ ± ∞ ¹ ~ (p=1.000 n=1) ² geomean 171.7µ 90.25µ -47.43% ¹ need >= 6 samples for confidence interval at level 0.95 ² need >= 4 samples to detect a difference at alpha level 0.05 │ master.bench │ pool.bench │ │ B/op │ B/op vs base │ SignRequest-8 15.03Ki ± ∞ ¹ 15.20Ki ± ∞ ¹ ~ (p=1.000 n=1) ² VerifyRequest-8 11.02Ki ± ∞ ¹ 10.87Ki ± ∞ ¹ ~ (p=1.000 n=1) ² geomean 12.87Ki 12.85Ki -0.12% ¹ need >= 6 samples for confidence interval at level 0.95 ² need >= 4 samples to detect a difference at alpha level 0.05 │ master.bench │ pool.bench │ │ allocs/op │ allocs/op vs base │ SignRequest-8 158.0 ± ∞ ¹ 159.0 ± ∞ ¹ ~ (p=1.000 n=1) ² VerifyRequest-8 129.0 ± ∞ ¹ 130.0 ± ∞ ¹ ~ (p=1.000 n=1) ² geomean 142.8 143.8 +0.70% ¹ need >= 6 samples for confidence interval at level 0.95 ² need >= 4 samples to detect a difference at alpha level 0.05 ```
dstepanov-yadro added 6 commits 2023-03-07 07:35:08 +00:00
Update go version 1.17 -> 1.18

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
Split methods to separate files, drop redundant intefaces

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
Add benchmarks for sign and verify methods

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
Sign request/response parts in parallel

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
Verify request/response parts in parallel

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
Fix test run version

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
dstepanov-yadro requested review from fyrchik 2023-03-07 07:35:34 +00:00
dstepanov-yadro requested review from carpawell 2023-03-07 07:35:34 +00:00
dstepanov-yadro requested review from storage-core-developers 2023-03-07 07:35:45 +00:00
fyrchik requested review from storage-core-committers 2023-03-07 07:47:14 +00:00
fyrchik reviewed 2023-03-07 07:55:13 +00:00
fyrchik left a comment
Owner

Speaking of buffers pool, do we need a local benchmark for this?

Speaking of buffers pool, do we need a local benchmark for this?
@ -17,1 +13,4 @@
var wrapperPool = sync.Pool{
New: func() any {
return &StableMarshalerWrapper{}
Owner

Can we instead just use StableMarshalerWrapper directly and make method receiver pointerless (it seems they already are)?

Can we instead just use `StableMarshalerWrapper` directly and make method receiver pointerless (it seems they already are)?
Author
Member

Don't understand you. StableMarshalerWrapper is used to convert stableMarshaller interface to DataSource integface.

Don't understand you. StableMarshalerWrapper is used to convert stableMarshaller interface to DataSource integface.
Owner

I've meant &StableMarshalerWrapper{SM: msg} allocates but with StableMarshalerWrapper{SM: msg} we, probably, do not need pool at all.

I've meant `&StableMarshalerWrapper{SM: msg}` allocates but with `StableMarshalerWrapper{SM: msg}` we, probably, do not need pool at all.
Author
Member

Fixed.

Fixed.
Contributor

mb a separate commit for that then? freezed me a little when saw that change in the "Add buffer pool"

mb a separate commit for that then? freezed me a little when saw that change in the "Add buffer pool"
Contributor

... or not according to @fyrchik's:

The last 4 commits are really a single commit -- "add buffer pool", can we squash them?

up to you then

... or not according to @fyrchik's: > The last 4 commits are really a single commit -- "add buffer pool", can we squash them? up to you then
Owner

I missed that part -- in Drop marshaler wrapper pool we actually also removed a pointer wrom the wrapper.

I missed that part -- in `Drop marshaler wrapper pool` we actually also removed a pointer wrom the wrapper.
@ -0,0 +10,4 @@
var buffersPool = sync.Pool{
New: func() any {
return &buffer{}
Owner

Why do you return *buffer and not []byte?

Why do you return `*buffer` and not `[]byte`?
Author
Member

This makes easier to create new buffer here:

	if cap(result.buf) < size {
		result.buf = make([]byte, size)

It just creates a new slice in case of current capacity does not meet the requested size.

This makes easier to create new buffer here: ``` if cap(result.buf) < size { result.buf = make([]byte, size) ``` It just creates a new slice in case of current capacity does not meet the requested size.
Owner

But how is cap(buf) < size and buf = make... different? Besides being able to implement free method on them (could be function as well).

But how is `cap(buf) < size` and `buf = make...` different? Besides being able to implement `free` method on them (could be function as well).
Author
Member

You are right. Fixed.

You are right. Fixed.
fyrchik marked this conversation as resolved
Author
Member

Speaking of buffers pool, do we need a local benchmark for this?

There are two benchmarks already (sign and verify) that use pool.

> Speaking of buffers pool, do we need a local benchmark for this? There are two benchmarks already (sign and verify) that use pool.
Owner

Speaking of buffers pool, do we need a local benchmark for this?

There are two benchmarks already (sign and verify) that use pool.

They are single-threaded now (and I think we need them written this way).

If using pool provides some improvements, could you attach benchmark diff to a commit message?

> > Speaking of buffers pool, do we need a local benchmark for this? > > There are two benchmarks already (sign and verify) that use pool. They are single-threaded now (and I think we need them written this way). If using pool provides some improvements, could you attach benchmark diff to a commit message?
dstepanov-yadro force-pushed feat/refactor-signservicemessage from 7f9809b7eb to 311ce95cb3 2023-03-07 15:08:14 +00:00 Compare
Owner

The last 4 commits are really a single commit -- "add buffer pool", can we squash them?
Introducing and dropping marshaler pool is not something we would like to see in history. May be we could mention about trying it in the PR message, though.
Adding a buffer pool and fixing it could become more readable too as an atomic change.

The last 4 commits are really a single commit -- "add buffer pool", can we squash them? Introducing and dropping marshaler pool is not something we would like to see in history. May be we could mention about trying it in the PR message, though. Adding a buffer pool and fixing it could become more readable too as an atomic change.
dstepanov-yadro force-pushed feat/refactor-signservicemessage from 311ce95cb3 to 18631efdaf 2023-03-09 08:36:16 +00:00 Compare
Author
Member

The last 4 commits are really a single commit -- "add buffer pool", can we squash them?
Introducing and dropping marshaler pool is not something we would like to see in history. May be we could mention about trying it in the PR message, though.
Adding a buffer pool and fixing it could become more readable too as an atomic change.

Done

> The last 4 commits are really a single commit -- "add buffer pool", can we squash them? > Introducing and dropping marshaler pool is not something we would like to see in history. May be we could mention about trying it in the PR message, though. > Adding a buffer pool and fixing it could become more readable too as an atomic change. Done
fyrchik approved these changes 2023-03-09 11:10:49 +00:00
carpawell reviewed 2023-03-09 16:31:04 +00:00
@ -18,3 +18,3 @@
strategy:
matrix:
go: [ '1.17.x', '1.18.x', '1.19.x' ]
go: [ '1.18.x', '1.19.x', '1.20.x' ]
Contributor

i think that should be either removed or changed in the same commit that updates go version

i think that should be either removed or changed in the same commit that updates `go` version
Author
Member

fixed

fixed
Contributor

well, PR that removes that file has been merged first :)

well, PR that removes that file has been merged first :)
carpawell marked this conversation as resolved
@ -175,0 +47,4 @@
body := serviceMessageBody(v)
meta := v.GetMetaHeader()
header := v.GetVerificationHeader()
if err := signMessageParts(key, body, meta, header, header != nil, result); err != nil {
Contributor

why do we pass both header and header != nil?

why do we pass both `header` and `header != nil`?
Author
Member

because of go:

package main

import (
	"fmt"
)

type typeI interface{
	Do() error
}

type typeT struct {
}

func (v *typeT) Do() error {
	return nil
}

func main() {
	var vI typeI
	var vT *typeT
	isNill(vI) //true
	isNill(nil) //true
	isNill(vT) //false
}


func isNill(v typeI) {
	fmt.Println(v == nil)
}
because of go: ```golang package main import ( "fmt" ) type typeI interface{ Do() error } type typeT struct { } func (v *typeT) Do() error { return nil } func main() { var vI typeI var vT *typeT isNill(vI) //true isNill(nil) //true isNill(vT) //false } func isNill(v typeI) { fmt.Println(v == nil) } ```
Contributor

oh, it is an interface in the func's definition, missed that

oh, it is an interface in the func's definition, missed that
carpawell marked this conversation as resolved
@ -73,0 +79,4 @@
for i := 0; i < b.N; i++ {
b.StopTimer()
dec := new(accounting.Decimal)
Contributor

why do we create the same message inside every bench cycle?

why do we create the same message inside every bench cycle?
Author
Member

because sign methods creates origin at every call, so it's like matryoshka. so every cycle step signs not one message.

because sign methods creates origin at every call, so it's like matryoshka. so every cycle step signs not one message.
carpawell marked this conversation as resolved
@ -0,0 +22,4 @@
func returnBufferToPool(buf []byte) {
if cap(buf) > poolSliceMaxSize {
buf = nil
Contributor

is there any practical case when we put nil slice and it helps us?

is there any practical case when we put `nil` slice and it helps us?
Author
Member

Fixed

Fixed
carpawell marked this conversation as resolved
dstepanov-yadro force-pushed feat/refactor-signservicemessage from 18631efdaf to fe59664de1 2023-03-10 07:21:54 +00:00 Compare
dstepanov-yadro force-pushed feat/refactor-signservicemessage from fe59664de1 to 7655227773 2023-03-10 07:39:34 +00:00 Compare
carpawell approved these changes 2023-03-10 10:23:06 +00:00
carpawell reviewed 2023-03-10 10:25:45 +00:00
dstepanov-yadro force-pushed feat/refactor-signservicemessage from 7655227773 to ec0d0274fa 2023-03-10 10:36:41 +00:00 Compare
fyrchik merged commit ec0d0274fa into master 2023-03-10 10:54:48 +00:00
Sign in to join this conversation.
No reviewers
TrueCloudLab/storage-core-developers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: TrueCloudLab/frostfs-api-go#8
No description provided.