aboutsummaryrefslogtreecommitdiffstats
path: root/prog
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2024-03-20 15:07:42 +0100
committerAleksandr Nogikh <nogikh@google.com>2024-03-20 14:50:51 +0000
commit6753db5cdc04330ec9d1a5116b890c19481d69b3 (patch)
tree040473e4831ebe962743fe9f88fc0b3b2c218f4d /prog
parent5b7d42ae0076f983317dceae96a942ea9d07c29c (diff)
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.
Diffstat (limited to 'prog')
-rw-r--r--prog/clone.go5
-rw-r--r--prog/rand.go13
2 files changed, 12 insertions, 6 deletions
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.