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

Performance Issue Comparing Array Types #353

Open
lmittmann opened this issue Feb 2, 2024 · 1 comment
Open

Performance Issue Comparing Array Types #353

lmittmann opened this issue Feb 2, 2024 · 1 comment

Comments

@lmittmann
Copy link

I ran into an issue where the comparison of a struct type containing lots of arrays took super long. After adding cmpopts.EquateComparable to the check the comparison is more than 10x faster. I think it should be okay to compare arrays of basic types (e.g. [32]byte) using == by default.

Example Benchmark:

func BenchmarkCmp(b *testing.B) {
	var v0, v1 [32]byte
	b.Run("plain", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			cmp.Diff(v0, v1)
		}
	})

	b.Run("comparable", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			cmp.Diff(v0, v1, cmpopts.EquateComparable([32]byte{}))
		}
	})

	type S struct {
		A [32]byte
		B [32]byte
		C [32]byte
		D []struct {
			E [32]byte
			F [32]byte
		}
	}
	var s0, s1 S
	b.Run("struct_plain", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			cmp.Diff(s0, s1)
		}
	})

	b.Run("struct_comparable", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			cmp.Diff(s0, s1, cmpopts.EquateComparable([32]byte{}))
		}
	})
}

Results:

                        │    sec/op    │
Cmp/plain-8               7.451µ ±  3%
Cmp/comparable-8          4.816µ ±  6%
Cmp/struct_plain-8        32.92µ ± 29%
Cmp/struct_comparable-8   13.56µ ±  5%
@dsnet
Copy link
Collaborator

dsnet commented Feb 9, 2024

This is not specific to [N]byte but also []byte.

As a point of semantic correctness we have to descend into each individual byte element if there were any options that are possibly applicable. However, we could short-circuit the evaluation if we detect that no option could possibly be applicable. Note that if the caller passes in any cmp.FilterPath options, then we cannot do the short-circuit since this option is Turing complete and we cannot prove that it wouldn't match on individual byte values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants