Skip to content

ING-1422: Add microbenchmarks#369

Open
Westwooo wants to merge 5 commits intomasterfrom
ING-1422-CI-microbenchmarks
Open

ING-1422: Add microbenchmarks#369
Westwooo wants to merge 5 commits intomasterfrom
ING-1422-CI-microbenchmarks

Conversation

@Westwooo
Copy link
Contributor

@Westwooo Westwooo commented Feb 18, 2026

Add comprehensive microbenchmarks for crud.go covering all CRUD operations with deterministic, network-free execution suitable for CI regression detection. Uses minimal purpose-built stubs instead of moq mocks for stability.

@Westwooo Westwooo force-pushed the ING-1422-CI-microbenchmarks branch 2 times, most recently from fb8aae0 to dffee43 Compare February 18, 2026 10:24
@Westwooo Westwooo requested a review from Copilot February 18, 2026 12:44
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new microbenchmark suite for CrudComponent operations, using purpose-built in-memory stubs to keep execution deterministic and network-free for CI performance regression tracking.

Changes:

  • Introduces crud_bench_test.go with minimal RetryManager, CollectionResolver, VbucketRouter, KvEndpointClientProvider, and KvClient stubs for benchmarking.
  • Adds benchmarks for orchestration overhead and a range of CRUD/subdoc/meta/stat operations, including compression and projection/fallback paths.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Westwooo Westwooo force-pushed the ING-1422-CI-microbenchmarks branch from d9d236a to 92dd19e Compare February 19, 2026 10:58
Add comprehensive microbenchmarks for crud.go covering all CRUD
operations with deterministic, network-free execution suitable for
CI regression detection. Uses minimal purpose-built stubs instead
of moq mocks for stability.
Uses NewKvClient() with a custom DialMemdxClientFunc that returns
benchMemdClient, exercising actual memdx packet encoding/decoding
code paths.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

brett19
brett19 previously approved these changes Feb 23, 2026
@Westwooo Westwooo force-pushed the ING-1422-CI-microbenchmarks branch from 7fb794b to 93f7c14 Compare February 25, 2026 08:54
@Westwooo Westwooo changed the title ING-1422: Adds microbenchmarks for CRUD operations ING-1422: Add microbenchmarks Feb 25, 2026
@Westwooo Westwooo requested a review from Copilot February 25, 2026 13:22
@Westwooo Westwooo force-pushed the ING-1422-CI-microbenchmarks branch from 68ebb1a to 631b26c Compare February 25, 2026 13:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 35 to 40
if idx := len(hostname) - 1; idx > 0 {
for i := idx; i >= 0; i-- {
if hostname[i] == ':' {
hostname = hostname[:i]
break
}
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The condition if idx := len(hostname) - 1; idx > 0 is unnecessary and adds complexity without benefit. The inner for loop for i := idx; i >= 0; i-- already handles all cases correctly, including when the hostname is empty or has no colon. This differs from the simpler approach in cbsearchx/search_int_bench_test.go (lines 39-44) which directly uses for i := len(hostname) - 1; i >= 0; i--. Consider removing the outer if statement for consistency and simplicity.

Suggested change
if idx := len(hostname) - 1; idx > 0 {
for i := idx; i >= 0; i-- {
if hostname[i] == ':' {
hostname = hostname[:i]
break
}
for i := len(hostname) - 1; i >= 0; i-- {
if hostname[i] == ':' {
hostname = hostname[:i]
break

Copilot uses AI. Check for mistakes.
Comment on lines +102 to +104
strings.Contains(err.Error(), "no planPIndexes for index") {
return false
}
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The error handling in the Eventually check may have incorrect logic. When an error occurs that is NOT one of the expected transient errors (ErrNoIndexPartitionsPlanned, ErrNoIndexPartitionsFound, ErrIndexNotFound, or "no planPIndexes for index"), the function returns true, indicating success. This means that unexpected errors will cause the polling to stop and the test to proceed, which could lead to false positives. Consider returning false for unexpected errors or explicitly handling them to ensure the test fails appropriately.

Suggested change
strings.Contains(err.Error(), "no planPIndexes for index") {
return false
}
strings.Contains(err.Error(), "no planPIndexes for index") {
// Known transient errors: index is not ready yet, keep retrying.
return false
}
// Unexpected error: log and keep retrying until timeout causes failure.
b.Logf("unexpected error while waiting for index %q to become queryable: %v", indexName, err)
return false

Copilot uses AI. Check for mistakes.
intBenchCreateDocument(ctx, b, agent, key, []byte(benchSmallDoc))

// Wait for replication
time.Sleep(500 * time.Millisecond)
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The fixed 500ms sleep for waiting for replication is problematic. In a benchmark context, this fixed delay will be included in the setup time before b.ResetTimer() is called, which is correct. However, 500ms may not be sufficient for replication to complete in all environments, leading to flaky benchmarks. Consider either increasing the timeout, implementing a polling mechanism to verify replication completion, or documenting that this benchmark requires a replica to be configured and may be flaky in certain environments.

Copilot uses AI. Check for mistakes.
require.NoError(b, err, "failed to create test document")
}

// intBenchCreateCounter creates a counter counter benchmarks
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The comment has a typo: "counter counter benchmarks" should be "counter for benchmarks".

Suggested change
// intBenchCreateCounter creates a counter counter benchmarks
// intBenchCreateCounter creates a counter for benchmarks

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +321 to +328
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, err := agent.Delete(ctx, &gocbcorex.DeleteOptions{
Key: []byte(keys[i]),
ScopeName: "",
CollectionName: "",
})
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

This benchmark converts keys[i] from string to []byte inside the timed loop ([]byte(keys[i])), which allocates every iteration and skews ReportAllocs/throughput. Precompute [][]byte keys (or reuse a single options struct and update its Key) before ResetTimer().

Suggested change
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, err := agent.Delete(ctx, &gocbcorex.DeleteOptions{
Key: []byte(keys[i]),
ScopeName: "",
CollectionName: "",
})
// Precompute []byte keys to avoid per-iteration allocations in the benchmark loop
keyBytes := make([][]byte, b.N)
for i := 0; i < b.N; i++ {
keyBytes[i] = []byte(keys[i])
}
// Reuse a single DeleteOptions instance across iterations
opts := &gocbcorex.DeleteOptions{
ScopeName: "",
CollectionName: "",
}
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
opts.Key = keyBytes[i]
_, err := agent.Delete(ctx, opts)

Copilot uses AI. Check for mistakes.
Comment on lines +411 to +416
_, err := agent.Unlock(ctx, &gocbcorex.UnlockOptions{
Key: []byte(keys[i]),
ScopeName: "",
CollectionName: "",
Cas: casValues[i],
})
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

This benchmark converts keys[i] from string to []byte inside the timed loop ([]byte(keys[i])), which allocates every iteration and skews ReportAllocs. Precompute [][]byte keys (and/or options structs) before ResetTimer().

Copilot uses AI. Check for mistakes.
Comment on lines +463 to +468
_, err := agent.GetAndLock(ctx, &gocbcorex.GetAndLockOptions{
Key: []byte(keys[i]),
ScopeName: "",
CollectionName: "",
LockTime: 30,
})
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

This benchmark converts keys[i] from string to []byte inside the timed loop ([]byte(keys[i])), which allocates every iteration and skews ReportAllocs. Precompute [][]byte keys (and/or options structs) before ResetTimer().

Copilot uses AI. Check for mistakes.
Comment on lines +489 to +494
_, err := agent.Add(ctx, &gocbcorex.AddOptions{
Key: []byte(keys[i]),
ScopeName: "",
CollectionName: "",
Value: []byte(benchDoc1KB),
})
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

This benchmark converts keys[i] from string to []byte inside the timed loop ([]byte(keys[i])), which allocates every iteration and skews ReportAllocs. Precompute [][]byte keys (and/or options structs) before ResetTimer().

Copilot uses AI. Check for mistakes.
Comment on lines +666 to +672
_, err := agent.AddWithMeta(ctx, &gocbcorex.AddWithMetaOptions{
Key: []byte(keys[i]),
ScopeName: "",
CollectionName: "",
Value: []byte(benchSmallDoc),
StoreCas: 1,
})
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

This benchmark converts keys[i] from string to []byte inside the timed loop ([]byte(keys[i])), which allocates every iteration and skews ReportAllocs. Precompute [][]byte keys (and/or options structs) before ResetTimer().

Copilot uses AI. Check for mistakes.
Comment on lines +721 to +727
_, err := agent.DeleteWithMeta(ctx, &gocbcorex.DeleteWithMetaOptions{
Key: []byte(keys[i]),
ScopeName: "",
CollectionName: "",
StoreCas: 1,
Options: memdx.MetaOpFlagSkipConflictResolution,
})
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

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

This benchmark converts keys[i] from string to []byte inside the timed loop ([]byte(keys[i])), which allocates every iteration and skews ReportAllocs. Precompute [][]byte keys (and/or options structs) before ResetTimer().

Copilot uses AI. Check for mistakes.
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.

3 participants