Skip to content

Commit 0fc67e6

Browse files
authored
dlog transfer service: benchmark tests #1278 (#1279)
Signed-off-by: Angelo De Caro <[email protected]>
1 parent 9b3b905 commit 0fc67e6

File tree

18 files changed

+1715
-443
lines changed

18 files changed

+1715
-443
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ The project will be subject to rapid changes to complete the open-sourcing proce
1414
# Useful Links
1515

1616
- [`Documentation`](./docs/design.md): Discover the design principles of the Fabric Token SDK.
17-
- [`Education Sessions`](./docs/education/README.md): Detailed education sessions with code walkthroughs of the Fabric Token SDK.
17+
- [`Education Sessions`](./docs/education/README.md): Detailed education sessions with code walkthrough of the Fabric Token SDK.
1818
- [`Fabric Samples`](https://github.com/hyperledger/fabric-samples/tree/main/token-sdk) Token SDK sample application is the
1919
quickest way to get a full network running with a REST API to issue, transfer and redeem tokens right away.
20+
- [`Benchmarks`](./docs/benchmark/benchmark.md): Benchmark guidelines and reports.
2021
- `Feedback`: Your help is the key to the success of the Fabric Token SDK.
2122
- Submit your issues [`here`][`fabric-token-sdk` Issues].
2223
- Found a bug? Need help to fix an issue? You have a great idea for a new feature? Talk to us! You can reach us on
2324
[Discord](https://discord.gg/hyperledger) in #fabric-token-sdk.
2425

2526
- [`Fabric Smart Client`](https://github.com/hyperledger-labs/fabric-smart-client): The Token SDK leverages the
2627
`Fabric Smart Client` for transaction orchestration, storing tokens and wallets, and more. Check it out.
27-
-
28+
2829
# Getting started
2930

3031
Clone the code and make sure it is on your `$GOPATH`.

docs/benchmark/benchmark.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Benchmark
2+
3+
- [Go Tools for Benchmarks](./tools.md)
4+
- [ZKAT DLog No Graph-Hiding](./dlognogh.md)

docs/benchmark/dlognogh.md

Lines changed: 605 additions & 0 deletions
Large diffs are not rendered by default.

docs/benchmark/tools.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Go Benchmark
2+
3+
This Section details how to execute Go benchmarks using the `go test` command and analyze the results with `benchstat`.
4+
5+
## 1. Running Benchmarks: Core Flags
6+
7+
To run benchmarks, use the `go test` command with specific flags. The most essential flag is `-bench`, which accepts a regular expression to select which benchmark functions to execute.
8+
9+
### Execution Control Flags
10+
11+
| Flag | Description | Example |
12+
| :--- | :--- | :--- |
13+
| `-bench=<regexp>` | Run benchmarks matching the regex. Use `.` to run all. | `-bench=.` |
14+
| `-run=<regexp>` | Run unit tests matching the regex. Use `^$` to skip all unit tests and only run benchmarks. | `-run=^$` |
15+
| `-benchtime=<t>` | Duration to run each benchmark (default `1s`). Can also specify iterations (suffix `x`). | `-benchtime=5s` or `-benchtime=1000x` |
16+
| `-count=<n>` | Run each benchmark `n` times. Essential for statistical analysis with `benchstat`. | `-count=10` |
17+
| `-timeout=<t>` | Overrides the default 10m timeout. Necessary for long-running benchmark suites. | `-timeout=30m` |
18+
| `-failfast` | Stop execution immediately after the first failure. | `-failfast` |
19+
20+
### Resource & Profiling Flags
21+
22+
These flags are critical for performance tuning and memory analysis, which aligns with your recent work on allocation optimization.
23+
24+
| Flag | Description | Example |
25+
| :--- | :--- | :--- |
26+
| `-benchmem` | Print memory allocation statistics (allocations per op, bytes per op). | `-benchmem` |
27+
| `-cpu=<n,m...>` | Run benchmarks with specific `GOMAXPROCS` values. | `-cpu=1,2,4,8` |
28+
| `-cpuprofile=<file>` | Write a CPU profile to the specified file. | `-cpuprofile=cpu.out` |
29+
| `-memprofile=<file>` | Write a memory profile to the specified file. | `-memprofile=mem.out` |
30+
| `-blockprofile=<file>`| Write a goroutine blocking profile (contention analysis). | `-blockprofile=block.out` |
31+
| `-mutexprofile=<file>`| Write a mutex contention profile. | `-mutexprofile=mutex.out` |
32+
| `-trace=<file>` | Write an execution trace for the `go tool trace` viewer. | `-trace=trace.out` |
33+
34+
> **Note:** When using profiling flags like `-cpuprofile`, the resulting binary is preserved in the current directory for analysis with `go tool pprof`.
35+
36+
## 2. The Analysis Workflow (A/B Testing)
37+
38+
Reliable performance optimization requires measuring the "before" and "after" states. The standard workflow involves saving benchmark output to files and comparing them.
39+
40+
### Step 1: Install Benchstat
41+
42+
`benchstat` is the standard tool for computing statistical summaries and comparing Go benchmarks.
43+
```bash
44+
go install golang.org/x/perf/cmd/benchstat@latest
45+
```
46+
or
47+
48+
```shell
49+
make install-tools
50+
```
51+
52+
### Step 2: Capture Baseline (Old)
53+
54+
Run the current code 10 times to gather statistically significant data.
55+
```bash
56+
# Save current performance to old.txt
57+
go test -bench=. -benchmem -count=10 -run=^$ . > old.txt
58+
```
59+
60+
### Step 3: Capture Experiment (New)
61+
62+
Apply your code changes (e.g., the allocation optimizations you researched) and run the same benchmark command.
63+
```bash
64+
# Save optimized performance to new.txt
65+
go test -bench=. -benchmem -count=10 -run=^$ . > new.txt
66+
```
67+
68+
## 3. Analyzing Results with Benchstat
69+
70+
Run `benchstat` against your two captured files to see the delta.
71+
72+
```bash
73+
benchstat old.txt new.txt
74+
```
75+
76+
### Interpreting the Output
77+
78+
The output displays the mean value for each metric and the percentage change.
79+
80+
```text
81+
name old time/op new time/op delta
82+
JSONEncode-8 1.50µs ± 2% 1.20µs ± 1% -20.00% (p=0.000 n=10+10)
83+
84+
name old alloc/op new alloc/op delta
85+
JSONEncode-8 896B ± 0% 420B ± 0% -53.12% (p=0.000 n=10+10)
86+
```
87+
88+
* **delta:** The percentage change. Negative values indicate improvement (reduced time or allocations).
89+
* **p-value:** The probability that the difference is due to random noise. A value `< 0.05` is generally considered statistically significant.
90+
* **n=10+10:** Indicates 10 valid samples were used from both the old and new files.
91+
92+
### Advanced Grouping
93+
94+
If your benchmarks use configuration naming conventions (e.g., `Benchmark/Enc=json` vs `Benchmark/Enc=gob`), you can group results specifically.
95+
96+
```bash
97+
# Compare results grouping by a specific configuration key
98+
benchstat -col /Enc old.txt
99+
```
100+
101+
## 4. Best Practices for Accurate Results
102+
103+
* **Isolation:** Close high-CPU applications (browsers, IDE indexing) before running benchmarks to reduce noise.
104+
* **Count > 1:** Always use `-count` (ideally 5-10) to detect variance. Single runs are unreliable for optimization decisions.
105+
* **Run Filter:** Always use `-run=^$` to prevent unit tests from interfering with benchmark timing or output parsing.
106+
* **Stable Machine:** For mission-critical measurements, consider using a dedicated bare-metal machine or a cloud instance with pinned CPUs to avoid "noisy neighbor" effects.

token/core/zkatdlog/nogh/v1/issue.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ func (s *IssueService) Issue(ctx context.Context, issuerIdentity driver.Identity
112112
return nil, nil, err
113113
}
114114

115-
issuer := &issue.Issuer{}
116-
issuer.New(tokenType, &common.WrappedSigningIdentity{
115+
issuer := issue.NewIssuer(tokenType, &common.WrappedSigningIdentity{
117116
Identity: issuerIdentity,
118117
Signer: signer,
119118
}, pp)

token/core/zkatdlog/nogh/v1/issue/issue_test.go

Lines changed: 0 additions & 55 deletions
This file was deleted.

token/core/zkatdlog/nogh/v1/issue/issuer.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ type Issuer struct {
2929
Type token2.Type
3030
}
3131

32-
// New returns an Issuer as a function of the passed parameters
33-
func (i *Issuer) New(ttype token2.Type, signer common.SigningIdentity, pp *v1.PublicParams) {
34-
i.Signer = signer
35-
i.Type = ttype
36-
i.PublicParams = pp
32+
// NewIssuer returns an Issuer as a function of the passed parameters
33+
func NewIssuer(tokenType token2.Type, signer common.SigningIdentity, pp *v1.PublicParams) *Issuer {
34+
return &Issuer{
35+
Signer: signer,
36+
Type: tokenType,
37+
PublicParams: pp,
38+
}
3739
}
3840

3941
func (i *Issuer) GenerateZKIssue(values []uint64, owners [][]byte) (*Action, []*token.Metadata, error) {

0 commit comments

Comments
 (0)