3
0

Add/tweak tests for TypedVale.Clone

This commit is contained in:
Tomaž Jerman
2024-01-31 15:38:24 +01:00
parent ad6494e866
commit 280ae83376
2 changed files with 123 additions and 28 deletions
+12 -12
View File
@@ -60,13 +60,13 @@ func (v *Vars) Clone() (out TypedValue, err error) {
}
if len(v.value) > cloneParallelItemThreshold {
return v.cloneParallel()
return v.cloneParallel(cloneParallelItemThreshold)
}
return v.clone()
return v.cloneSeq()
}
func (v *Vars) clone() (out TypedValue, err error) {
func (v *Vars) cloneSeq() (out TypedValue, err error) {
aux := &Vars{
value: make(map[string]TypedValue, len(v.value)),
}
@@ -84,7 +84,7 @@ func (v *Vars) clone() (out TypedValue, err error) {
return aux, nil
}
func (v *Vars) cloneParallel() (out TypedValue, err error) {
func (v *Vars) cloneParallel(threshold int) (out TypedValue, err error) {
keys := make([]string, 0, len(v.value))
for k := range v.value {
keys = append(keys, k)
@@ -94,12 +94,12 @@ func (v *Vars) cloneParallel() (out TypedValue, err error) {
errors := make([]error, len(v.value))
wg := sync.WaitGroup{}
for i := 0; i < len(keys); i += cloneParallelItemThreshold {
for i := 0; i < len(keys); i += threshold {
wg.Add(1)
go func(i int) {
defer wg.Done()
for j, k := range keys[i:int(math.Min(float64(i+cloneParallelItemThreshold), float64(len(keys))-1))] {
for j, k := range keys[i:int(math.Min(float64(i+threshold), float64(len(keys))))] {
aux, err := v.value[k].Clone()
if err != nil {
errors[i+j] = err
@@ -961,13 +961,13 @@ func (v *Any) Clone() (out TypedValue, err error) {
func (v *Array) Clone() (out TypedValue, err error) {
if len(v.value) > cloneParallelItemThreshold {
return v.cloneParallel()
return v.cloneParallel(cloneParallelItemThreshold)
}
return v.clone()
return v.cloneSeq()
}
func (v *Array) clone() (_ TypedValue, err error) {
func (v *Array) cloneParallel(threshold int) (_ TypedValue, err error) {
errors := make([]error, len(v.value))
wg := sync.WaitGroup{}
@@ -975,12 +975,12 @@ func (v *Array) clone() (_ TypedValue, err error) {
value: make([]TypedValue, len(v.value)),
}
for i := 0; i < len(v.value); i += cloneParallelItemThreshold {
for i := 0; i < len(v.value); i += threshold {
wg.Add(1)
go func(i int) {
defer wg.Done()
for j, v := range v.value[i:int(math.Min(float64(i+cloneParallelItemThreshold), float64(len(v.value))-1))] {
for j, v := range v.value[i:int(math.Min(float64(i+threshold), float64(len(v.value))))] {
aux, err := v.Clone()
if err != nil {
errors[i+j] = err
@@ -1002,7 +1002,7 @@ func (v *Array) clone() (_ TypedValue, err error) {
return out, nil
}
func (v *Array) cloneParallel() (out TypedValue, err error) {
func (v *Array) cloneSeq() (out TypedValue, err error) {
aux := &Array{
value: make([]TypedValue, len(v.value)),
}
+111 -16
View File
@@ -551,31 +551,126 @@ func TestArrayDecode(t *testing.T) {
req.Len(foo.Values, 2)
}
func TestVarsClone(t *testing.T) {
var (
req = require.New(t)
v = &Vars{
value: map[string]TypedValue{
"a1": Must(NewInteger(1)),
"a2": Must(NewInteger(2)),
"a3": Must(NewInteger(3)),
"a4": Must(NewInteger(4)),
"a5": Must(NewInteger(5)),
"a6": Must(NewInteger(6)),
"a7": Must(NewInteger(7)),
"a8": Must(NewInteger(8)),
"a9": Must(NewInteger(9)),
"a10": Must(NewInteger(10)),
},
}
)
check := func(out TypedValue, err error) {
req.NoError(err)
outVars := out.(*Vars)
req.Len(outVars.value, len(v.value))
for k, v := range v.value {
req.Contains(outVars.value, k)
req.Equal(v.Get(), outVars.value[k].Get())
}
}
t.Run("sequential", func(t *testing.T) {
check(v.cloneSeq())
})
t.Run("parallel", func(t *testing.T) {
check(v.cloneParallel(2))
})
t.Run("parallel odd", func(t *testing.T) {
check(v.cloneParallel(3))
})
t.Run("parallel one chunk", func(t *testing.T) {
check(v.cloneParallel(11))
})
}
func TestArrayClone(t *testing.T) {
var (
req = require.New(t)
vv = &Array{
value: []TypedValue{
Must(NewInteger(1)),
Must(NewInteger(2)),
Must(NewInteger(3)),
Must(NewInteger(4)),
Must(NewInteger(5)),
Must(NewInteger(6)),
Must(NewInteger(7)),
Must(NewInteger(8)),
Must(NewInteger(9)),
Must(NewInteger(10)),
},
}
)
check := func(out TypedValue, err error) {
req.NoError(err)
outArray := out.(*Array)
req.Len(outArray.value, len(vv.value))
for i, v := range vv.value {
req.Equal(v.Get(), outArray.value[i].Get())
}
}
t.Run("sequential", func(t *testing.T) {
check(vv.cloneSeq())
})
t.Run("parallel", func(t *testing.T) {
check(vv.cloneParallel(2))
})
t.Run("parallel odd", func(t *testing.T) {
check(vv.cloneParallel(3))
})
t.Run("parallel one chunk", func(t *testing.T) {
check(vv.cloneParallel(11))
})
}
// Original
// goos: darwin
// goarch: arm64
// pkg: github.com/cortezaproject/corteza/server/pkg/expr
// BenchmarkVarsUnref_10_10-12 2623 459222 ns/op 370399 B/op 4886 allocs/op
// BenchmarkVarsUnref_100_100-12 25 46813440 ns/op 42108291 B/op 453755 allocs/op
// BenchmarkVarsUnref_1000_1000-12 1 4572438792 ns/op 4004143648 B/op 45064443 allocs/op
// BenchmarkVarsClone_10_10-12 2623 459222 ns/op 370399 B/op 4886 allocs/op
// BenchmarkVarsClone_100_100-12 25 46813440 ns/op 42108291 B/op 453755 allocs/op
// BenchmarkVarsClone_1000_1000-12 1 4572438792 ns/op 4004143648 B/op 45064443 allocs/op
// Reworked, all seq.
// goos: darwin
// goarch: arm64
// pkg: github.com/cortezaproject/corteza/server/pkg/expr
// BenchmarkVarsUnref_10_10-12 37764 31204 ns/op 90607 B/op 859 allocs/op
// BenchmarkVarsUnref_100_100-12 303 3630116 ns/op 9128270 B/op 80430 allocs/op
// BenchmarkVarsUnref_1000_1000-12 3 372980819 ns/op 898107160 B/op 8004031 allocs/op
// BenchmarkVarsClone_10_10-12 37764 31204 ns/op 90607 B/op 859 allocs/op
// BenchmarkVarsClone_100_100-12 303 3630116 ns/op 9128270 B/op 80430 allocs/op
// BenchmarkVarsClone_1000_1000-12 3 372980819 ns/op 898107160 B/op 8004031 allocs/op
// Reworked, seq threshold to parallel
// goos: darwin
// goarch: arm64
// pkg: github.com/cortezaproject/corteza/server/pkg/expr
// BenchmarkVarsUnref_10_10-12 35852 33396 ns/op 90606 B/op 859 allocs/op
// BenchmarkVarsUnref_100_100-12 320 3692905 ns/op 9128270 B/op 80430 allocs/op
// BenchmarkVarsUnref_1000_1000-12 7 175036667 ns/op 946114581 B/op 8003063 allocs/op
// BenchmarkVarsClone_10_10-12 35852 33396 ns/op 90606 B/op 859 allocs/op
// BenchmarkVarsClone_100_100-12 320 3692905 ns/op 9128270 B/op 80430 allocs/op
// BenchmarkVarsClone_1000_1000-12 7 175036667 ns/op 946114581 B/op 8003063 allocs/op
func benchmarkVarsUnref(b *testing.B, rootCount, nestedCount int) {
func benchmarkVarsClone(b *testing.B, rootCount, nestedCount int) {
nest := &Vars{
value: map[string]TypedValue{},
}
@@ -622,14 +717,14 @@ func benchmarkVarsUnref(b *testing.B, rootCount, nestedCount int) {
}
}
func BenchmarkVarsUnref_10_10(b *testing.B) {
benchmarkVarsUnref(b, 10, 10)
func BenchmarkVarsClone_10_10(b *testing.B) {
benchmarkVarsClone(b, 10, 10)
}
func BenchmarkVarsUnref_100_100(b *testing.B) {
benchmarkVarsUnref(b, 100, 100)
func BenchmarkVarsClone_100_100(b *testing.B) {
benchmarkVarsClone(b, 100, 100)
}
func BenchmarkVarsUnref_1000_1000(b *testing.B) {
benchmarkVarsUnref(b, 1000, 1000)
func BenchmarkVarsClone_1000_1000(b *testing.B) {
benchmarkVarsClone(b, 1000, 1000)
}