Add benchmarks for merge package

This is testing the high-level part of SMD, we would probably need
lower-level benchmarks in this repo, but this at least gives us a
general idea of the direction.
diff --git a/merge/deduced_test.go b/merge/deduced_test.go
index 8d59c9e..7ec78f2 100644
--- a/merge/deduced_test.go
+++ b/merge/deduced_test.go
@@ -534,3 +534,280 @@
 		})
 	}
 }
+
+func BenchmarkDeducedSimple(b *testing.B) {
+	test := TestCase{
+		Ops: []Operation{
+			Apply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+						numeric: 1
+						string: "string"
+					`,
+			},
+			Update{
+				Manager:    "controller",
+				APIVersion: "v1",
+				Object: `
+						numeric: 1
+						string: "controller string"
+						bool: true
+					`,
+			},
+			Apply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+						numeric: 2
+						string: "user string"
+					`,
+				Conflicts: merge.Conflicts{
+					merge.Conflict{Manager: "controller", Path: _P("string")},
+				},
+			},
+			ForceApply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+						numeric: 2
+						string: "user string"
+					`,
+			},
+		},
+		Object: `
+				numeric: 2
+				string: "user string"
+				bool: true
+			`,
+		Managed: fieldpath.ManagedFields{
+			"default": fieldpath.NewVersionedSet(
+				_NS(
+					_P("numeric"), _P("string"),
+				),
+				"v1",
+				false,
+			),
+			"controller": fieldpath.NewVersionedSet(
+				_NS(
+					_P("bool"),
+				),
+				"v1",
+				false,
+			),
+		},
+	}
+
+	b.ReportAllocs()
+	for n := 0; n < b.N; n++ {
+		if err := test.Test(typed.DeducedParseableType); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkDeducedNested(b *testing.B) {
+	test := TestCase{
+		Ops: []Operation{
+			Apply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+						a: 1
+						b:
+						  c:
+						    d: 2
+						    e:
+						    - 1
+						    - 2
+						    - 3
+						    f:
+						    - name: n
+						      value: 1
+					`,
+			},
+			Update{
+				Manager:    "controller",
+				APIVersion: "v1",
+				Object: `
+						a: 1
+						b:
+						  c:
+						    d: 3
+						    e:
+						    - 1
+						    - 2
+						    - 3
+						    - 4
+						    f:
+						    - name: n
+						      value: 2
+						g: 5
+					`,
+			},
+			Apply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+						a: 2
+						b:
+						  c:
+						    d: 2
+						    e:
+						    - 3
+						    - 2
+						    - 1
+						    f:
+						    - name: n
+						      value: 1
+					`,
+				Conflicts: merge.Conflicts{
+					merge.Conflict{Manager: "controller", Path: _P("b", "c", "d")},
+					merge.Conflict{Manager: "controller", Path: _P("b", "c", "e")},
+					merge.Conflict{Manager: "controller", Path: _P("b", "c", "f")},
+				},
+			},
+			ForceApply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+						a: 2
+						b:
+						  c:
+						    d: 2
+						    e:
+						    - 3
+						    - 2
+						    - 1
+						    f:
+						    - name: n
+						      value: 1
+					`,
+			},
+		},
+		Object: `
+				a: 2
+				b:
+				  c:
+				    d: 2
+				    e:
+				    - 3
+				    - 2
+				    - 1
+				    f:
+				    - name: n
+				      value: 1
+				g: 5
+			`,
+	}
+
+	b.ReportAllocs()
+	for n := 0; n < b.N; n++ {
+		if err := test.Test(typed.DeducedParseableType); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkDeducedNestedAcrossVersion(b *testing.B) {
+	test := TestCase{
+		Ops: []Operation{
+			Apply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+					a: 1
+					b:
+					  c:
+					    d: 2
+					    e:
+					    - 1
+					    - 2
+					    - 3
+					    f:
+					    - name: n
+					      value: 1
+				`,
+			},
+			Update{
+				Manager:    "controller",
+				APIVersion: "v2",
+				Object: `
+					a: 1
+					b:
+					  c:
+					    d: 3
+					    e:
+					    - 1
+					    - 2
+					    - 3
+					    - 4
+					    f:
+					    - name: n
+					      value: 2
+					g: 5
+				`,
+			},
+			Apply{
+				Manager:    "default",
+				APIVersion: "v3",
+				Object: `
+					a: 2
+					b:
+					  c:
+					    d: 2
+					    e:
+					    - 3
+					    - 2
+					    - 1
+					    f:
+					    - name: n
+					      value: 1
+				`,
+				Conflicts: merge.Conflicts{
+					merge.Conflict{Manager: "controller", Path: _P("b", "c", "d")},
+					merge.Conflict{Manager: "controller", Path: _P("b", "c", "e")},
+					merge.Conflict{Manager: "controller", Path: _P("b", "c", "f")},
+				},
+			},
+			ForceApply{
+				Manager:    "default",
+				APIVersion: "v3",
+				Object: `
+					a: 2
+					b:
+					  c:
+					    d: 2
+					    e:
+					    - 3
+					    - 2
+					    - 1
+					    f:
+					    - name: n
+					      value: 1
+				`,
+			},
+		},
+		Object: `
+			a: 2
+			b:
+			  c:
+			    d: 2
+			    e:
+			    - 3
+			    - 2
+			    - 1
+			    f:
+			    - name: n
+			      value: 1
+			g: 5
+		`,
+	}
+
+	b.ReportAllocs()
+	for n := 0; n < b.N; n++ {
+		if err := test.Test(typed.DeducedParseableType); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/merge/leaf_test.go b/merge/leaf_test.go
index 6fe233d..c4760e9 100644
--- a/merge/leaf_test.go
+++ b/merge/leaf_test.go
@@ -467,3 +467,74 @@
 		})
 	}
 }
+
+func BenchmarkLeafConflictAcrossVersion(b *testing.B) {
+	test := TestCase{
+		Ops: []Operation{
+			Apply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+					numeric: 1
+					string: "string"
+				`,
+			},
+			Update{
+				Manager:    "controller",
+				APIVersion: "v2",
+				Object: `
+					numeric: 1
+					string: "controller string"
+					bool: true
+				`,
+			},
+			Apply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+					numeric: 2
+					string: "user string"
+				`,
+				Conflicts: merge.Conflicts{
+					merge.Conflict{Manager: "controller", Path: _P("string")},
+				},
+			},
+			ForceApply{
+				Manager:    "default",
+				APIVersion: "v1",
+				Object: `
+					numeric: 2
+					string: "user string"
+				`,
+			},
+		},
+		Object: `
+			numeric: 2
+			string: "user string"
+			bool: true
+		`,
+		Managed: fieldpath.ManagedFields{
+			"default": fieldpath.NewVersionedSet(
+				_NS(
+					_P("numeric"), _P("string"),
+				),
+				"v1",
+				false,
+			),
+			"controller": fieldpath.NewVersionedSet(
+				_NS(
+					_P("bool"),
+				),
+				"v2",
+				false,
+			),
+		},
+	}
+
+	b.ReportAllocs()
+	for n := 0; n < b.N; n++ {
+		if err := test.Test(leafFieldsParser); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/merge/multiple_appliers_test.go b/merge/multiple_appliers_test.go
index dbe168f..de72d5c 100644
--- a/merge/multiple_appliers_test.go
+++ b/merge/multiple_appliers_test.go
@@ -1026,3 +1026,87 @@
 func (r repeatingConverter) IsMissingVersionError(err error) bool {
 	return err == missingVersionError
 }
+
+func BenchmarkMultipleApplierRecursiveRealConversion(b *testing.B) {
+	test := TestCase{
+		Ops: []Operation{
+			Apply{
+				Manager: "apply-one",
+				Object: `
+					mapOfMapsRecursive:
+					  a:
+					    b:
+					  c:
+					    d:
+				`,
+				APIVersion: "v1",
+			},
+			Apply{
+				Manager: "apply-two",
+				Object: `
+					mapOfMapsRecursive:
+					  aa:
+					  cc:
+					    dd:
+				`,
+				APIVersion: "v2",
+			},
+			Update{
+				Manager: "controller",
+				Object: `
+					mapOfMapsRecursive:
+					  aaa:
+					    bbb:
+					      ccc:
+					        ddd:
+					  ccc:
+					    ddd:
+					      eee:
+					        fff:
+					`,
+				APIVersion: "v3",
+			},
+			Apply{
+				Manager: "apply-one",
+				Object: `
+					mapOfMapsRecursive:
+				`,
+				APIVersion: "v4",
+			},
+		},
+		Object: `
+			mapOfMapsRecursive:
+			  aaaa:
+			  cccc:
+			    dddd:
+			      eeee:
+			        ffff:
+		`,
+		Managed: fieldpath.ManagedFields{
+			"apply-two": fieldpath.NewVersionedSet(
+				_NS(
+					_P("mapOfMapsRecursive", "aa"),
+					_P("mapOfMapsRecursive", "cc"),
+					_P("mapOfMapsRecursive", "cc", "dd"),
+				),
+				"v2",
+				false,
+			),
+			"controller": fieldpath.NewVersionedSet(
+				_NS(
+					_P("mapOfMapsRecursive", "ccc", "ddd", "eee"),
+					_P("mapOfMapsRecursive", "ccc", "ddd", "eee", "fff"),
+				),
+				"v3",
+				false,
+			),
+		},
+	}
+
+	b.ReportAllocs()
+	for n := 0; n < b.N; n++ {
+		if err := test.TestWithConverter(nestedTypeParser, repeatingConverter{nestedTypeParser}); err != nil {
+			b.Fatal(err)
+		}
+	}
+}