From 6753db5cdc04330ec9d1a5116b890c19481d69b3 Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Wed, 20 Mar 2024 15:07:42 +0100 Subject: prog: optimize resourceCentric() In practice, we need to try out many different corpus programs before we may find a matching resource. It's very inefficient to Clone() each of them. This change gives a +76% speed improvement in the BenchmarkMutate() test. --- prog/clone.go | 5 ++++- prog/rand.go | 13 ++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'prog') diff --git a/prog/clone.go b/prog/clone.go index 4523be0eb..6ec28e39e 100644 --- a/prog/clone.go +++ b/prog/clone.go @@ -8,7 +8,10 @@ import ( ) func (p *Prog) Clone() *Prog { - newargs := make(map[*ResultArg]*ResultArg) + return p.cloneWithMap(make(map[*ResultArg]*ResultArg)) +} + +func (p *Prog) cloneWithMap(newargs map[*ResultArg]*ResultArg) *Prog { p1 := &Prog{ Target: p.Target, Calls: cloneCalls(p.Calls, newargs), diff --git a/prog/rand.go b/prog/rand.go index 742dbaa7c..0e3727c7f 100644 --- a/prog/rand.go +++ b/prog/rand.go @@ -943,12 +943,15 @@ func (r *randGen) resourceCentric(s *state, t *ResourceType, dir Dir) (arg Arg, var p *Prog var resource *ResultArg for _, idx := range r.Perm(len(s.corpus)) { - p = s.corpus[idx].Clone() - resources := getCompatibleResources(p, t.TypeName, r) - if len(resources) > 0 { - resource = resources[r.Intn(len(resources))] - break + corpusProg := s.corpus[idx] + resources := getCompatibleResources(corpusProg, t.TypeName, r) + if len(resources) == 0 { + continue } + argMap := make(map[*ResultArg]*ResultArg) + p = corpusProg.cloneWithMap(argMap) + resource = argMap[resources[r.Intn(len(resources))]] + break } // No compatible resource was found. -- cgit mrf-deployment