aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFumitoshi Ukai <fumitoshi.ukai@gmail.com>2015-06-18 15:36:57 +0900
committerFumitoshi Ukai <fumitoshi.ukai@gmail.com>2015-06-18 15:36:57 +0900
commitb8acae94bc5b6494f51fe1acf32df5d72d412562 (patch)
treec0e114c693abdacc5690ec3adf8dd1161c8983d1
parent7c9aa9f17d5f8f27aed62b5520b8fbc6be0103ac (diff)
downloadkati-b8acae94bc5b6494f51fe1acf32df5d72d412562.tar.gz
reduce runtime.convT2I -> runtime.newobject -> runtime.mallocgc
conversion from value to interface is more expensive than conversion from pointer to interface. package main import "testing" type I interface { String() string } type val struct { s string } func (v val) String() string { return v.s } type ptr struct { s string } func (p *ptr) String() string { return p.s } func BenchmarkT2IForValue(b *testing.B) { var intf I for i := 0; i < b.N; i++ { intf = val{"abc"} } _ = intf } func BenchmarkT2IForPtr(b *testing.B) { var intf I for i := 0; i < b.N; i++ { intf = &ptr{"abc"} } _ = intf } % go test -bench . a_test.go testing: warning: no tests to run PASS BenchmarkT2IForValue 20000000 90.9 ns/op BenchmarkT2IForPtr 20000000 76.8 ns/op ok command-line-arguments 3.539s
-rw-r--r--ast.go8
-rw-r--r--dep.go2
-rw-r--r--eval.go2
-rw-r--r--expr.go22
-rw-r--r--expr_test.go22
-rw-r--r--func.go12
-rw-r--r--main.go6
-rw-r--r--serialize.go8
-rw-r--r--var.go58
9 files changed, 70 insertions, 70 deletions
diff --git a/ast.go b/ast.go
index a519f4b..7a418be 100644
--- a/ast.go
+++ b/ast.go
@@ -57,13 +57,13 @@ func (ast *AssignAST) evalRHS(ev *Evaluator, lhs string) Var {
case ":=":
var buf bytes.Buffer
ast.rhs.Eval(&buf, ev)
- return SimpleVar{value: buf.Bytes(), origin: origin}
+ return &SimpleVar{value: buf.Bytes(), origin: origin}
case "=":
- return RecursiveVar{expr: ast.rhs, origin: origin}
+ return &RecursiveVar{expr: ast.rhs, origin: origin}
case "+=":
prev := ev.LookupVarInCurrentScope(lhs)
if !prev.IsDefined() {
- return RecursiveVar{expr: ast.rhs, origin: origin}
+ return &RecursiveVar{expr: ast.rhs, origin: origin}
}
return prev.AppendVar(ev, ast.rhs)
case "?=":
@@ -71,7 +71,7 @@ func (ast *AssignAST) evalRHS(ev *Evaluator, lhs string) Var {
if prev.IsDefined() {
return prev
}
- return RecursiveVar{expr: ast.rhs, origin: origin}
+ return &RecursiveVar{expr: ast.rhs, origin: origin}
default:
panic(fmt.Sprintf("unknown assign op: %q", ast.op))
}
diff --git a/dep.go b/dep.go
index a8d853e..0e29789 100644
--- a/dep.go
+++ b/dep.go
@@ -260,7 +260,7 @@ func (db *DepBuilder) buildPlan(output string, neededBy string, tsvs Vars) (*Dep
if vars != nil {
for name, v := range vars {
// TODO: Consider not updating db.vars.
- tsv := v.(TargetSpecificVar)
+ tsv := v.(*TargetSpecificVar)
restores = append(restores, db.vars.save(name))
restores = append(restores, tsvs.save(name))
switch tsv.op {
diff --git a/eval.go b/eval.go
index 417f945..b097c24 100644
--- a/eval.go
+++ b/eval.go
@@ -127,7 +127,7 @@ func (ev *Evaluator) setTargetSpecificVar(assign *AssignAST, output string) {
ev.currentScope = vars
lhs, rhs := ev.evalAssignAST(assign)
Logf("rule outputs:%q assign:%q=%q (flavor:%q)", output, lhs, rhs, rhs.Flavor())
- vars.Assign(lhs, TargetSpecificVar{v: rhs, op: assign.op})
+ vars.Assign(lhs, &TargetSpecificVar{v: rhs, op: assign.op})
ev.currentScope = nil
}
diff --git a/expr.go b/expr.go
index 6c63216..6dfaa69 100644
--- a/expr.go
+++ b/expr.go
@@ -26,7 +26,7 @@ import (
var (
errEndOfInput = errors.New("parse: unexpected end of input")
- errNotLiteral = errors.New("valueNum: not literal")
+ errNotLiteral = errors.New("valueNum: not literal")
bufFree = sync.Pool{
New: func() interface{} { return new(buffer) },
@@ -139,7 +139,7 @@ type varref struct {
varname Value
}
-func (v varref) String() string {
+func (v *varref) String() string {
varname := v.varname.String()
if len(varname) == 1 {
return fmt.Sprintf("$%s", varname)
@@ -147,7 +147,7 @@ func (v varref) String() string {
return fmt.Sprintf("${%s}", varname)
}
-func (v varref) Eval(w io.Writer, ev *Evaluator) {
+func (v *varref) Eval(w io.Writer, ev *Evaluator) {
te := traceEvent.begin("var", v, traceEventMain)
buf := newBuf()
v.varname.Eval(buf, ev)
@@ -157,13 +157,13 @@ func (v varref) Eval(w io.Writer, ev *Evaluator) {
traceEvent.end(te)
}
-func (v varref) Serialize() SerializableVar {
+func (v *varref) Serialize() SerializableVar {
return SerializableVar{
Type: "varref",
Children: []SerializableVar{v.varname.Serialize()},
}
}
-func (v varref) Dump(w io.Writer) {
+func (v *varref) Dump(w io.Writer) {
dumpByte(w, ValueTypeVarref)
v.varname.Dump(w)
}
@@ -316,7 +316,7 @@ Loop:
}
if bytes.IndexByte(term, in[i+1]) >= 0 {
expr = appendStr(expr, in[b:i], alloc)
- expr = append(expr, varref{varname: literal("")})
+ expr = append(expr, &varref{varname: literal("")})
i++
b = i
break Loop
@@ -388,7 +388,7 @@ func parseDollar(in []byte, alloc bool) (Value, int, error) {
if in[1] >= '0' && in[1] <= '9' {
return paramref(in[1] - '0'), 2, nil
}
- return varref{varname: str(in[1:2], alloc)}, 2, nil
+ return &varref{varname: str(in[1:2], alloc)}, 2, nil
}
term := []byte{paren, ':', ' '}
var varname Expr
@@ -410,7 +410,7 @@ Again:
// ${n}
return paramref(n), i + 1, nil
}
- return varref{varname: vname}, i + 1, nil
+ return &varref{varname: vname}, i + 1, nil
case ' ':
// ${e ...}
switch token := e.(type) {
@@ -424,7 +424,7 @@ Again:
continue Again
case ':':
// ${varname:...}
- colon := in[i:i+1]
+ colon := in[i : i+1]
term = term[:2]
term[1] = '=' // term={paren, '='}.
e, n, err := parseExpr(in[i+1:], term, alloc)
@@ -434,7 +434,7 @@ Again:
i += 1 + n
if in[i] == paren {
varname = appendStr(varname, colon, alloc)
- return varref{varname: varname}, i + 1, nil
+ return &varref{varname: varname}, i + 1, nil
}
// ${varname:xx=...}
pat := e
@@ -641,7 +641,7 @@ func matchExpr(expr, pat Expr) ([]Value, bool) {
for i := range expr {
if pat[i] == mv {
switch expr[i].(type) {
- case paramref, varref:
+ case paramref, *varref:
matches = append(matches, expr[i])
continue
}
diff --git a/expr_test.go b/expr_test.go
index dbf715a..9b776e0 100644
--- a/expr_test.go
+++ b/expr_test.go
@@ -47,11 +47,11 @@ func TestParseExpr(t *testing.T) {
},
{
in: "$foo",
- val: Expr{varref{varname: literal("f")}, literal("oo")},
+ val: Expr{&varref{varname: literal("f")}, literal("oo")},
},
{
in: "$(foo)",
- val: varref{varname: literal("foo")},
+ val: &varref{varname: literal("foo")},
},
{
in: "$(foo:.c=.o)",
@@ -68,13 +68,13 @@ func TestParseExpr(t *testing.T) {
fclosure: fclosure{
args: []Value{
literal("(subst"),
- varref{
+ &varref{
varname: literal("space"),
},
- varref{
+ &varref{
varname: literal(","),
},
- varref{
+ &varref{
varname: literal("foo"),
},
},
@@ -89,15 +89,15 @@ func TestParseExpr(t *testing.T) {
fclosure: fclosure{
args: []Value{
literal("(subst"),
- varref{
+ &varref{
varname: literal("space"),
},
- varref{
+ &varref{
varname: literal(""),
},
Expr{
literal(","),
- varref{
+ &varref{
varname: literal("foo"),
},
},
@@ -183,10 +183,10 @@ func TestParseExpr(t *testing.T) {
fclosure: fclosure{
args: []Value{
literal("(and"),
- varref{
+ &varref{
varname: literal("TRUE"),
},
- varref{
+ &varref{
varname: literal("X"),
},
},
@@ -245,7 +245,7 @@ func TestParseExpr(t *testing.T) {
val: &funcEvalAssign{
lhs: "foo",
op: ":=",
- rhs: varref{
+ rhs: &varref{
literal("bar"),
},
},
diff --git a/func.go b/func.go
index a7ec835..2ca7c24 100644
--- a/func.go
+++ b/func.go
@@ -809,7 +809,7 @@ func (f *funcCall) Eval(w io.Writer, ev *Evaluator) {
for i, arg := range args {
name := fmt.Sprintf("%d", i)
restores = append(restores, ev.outVars.save(name))
- ev.outVars.Assign(name, SimpleVar{
+ ev.outVars.Assign(name, &SimpleVar{
value: arg,
origin: "automatic", // ??
})
@@ -985,22 +985,22 @@ func (f *funcEvalAssign) Eval(w io.Writer, ev *Evaluator) {
}
var vbuf bytes.Buffer
expr.Eval(&vbuf, ev)
- rvalue = SimpleVar{value: tmpval(vbuf.Bytes()), origin: "file"}
+ rvalue = &SimpleVar{value: tmpval(vbuf.Bytes()), origin: "file"}
case "=":
- rvalue = RecursiveVar{expr: tmpval(rhs), origin: "file"}
+ rvalue = &RecursiveVar{expr: tmpval(rhs), origin: "file"}
case "+=":
prev := ev.LookupVar(f.lhs)
if prev.IsDefined() {
rvalue = prev.Append(ev, string(rhs))
} else {
- rvalue = RecursiveVar{expr: tmpval(rhs), origin: "file"}
+ rvalue = &RecursiveVar{expr: tmpval(rhs), origin: "file"}
}
case "?=":
prev := ev.LookupVar(f.lhs)
if prev.IsDefined() {
return
}
- rvalue = RecursiveVar{expr: tmpval(rhs), origin: "file"}
+ rvalue = &RecursiveVar{expr: tmpval(rhs), origin: "file"}
}
Logf("Eval ASSIGN: %s=%q (flavor:%q)", f.lhs, rvalue, rvalue.Flavor())
ev.outVars.Assign(f.lhs, rvalue)
@@ -1111,7 +1111,7 @@ func (f *funcForeach) Eval(w io.Writer, ev *Evaluator) {
for ws.Scan() {
word := ws.Bytes()
ev.outVars.Assign(varname,
- SimpleVar{
+ &SimpleVar{
value: tmpval(word),
origin: "automatic",
})
diff --git a/main.go b/main.go
index 466d93e..41eea88 100644
--- a/main.go
+++ b/main.go
@@ -216,19 +216,19 @@ func getDepGraph(clvars []string, targets []string) *DepGraph {
if len(kv) < 2 {
panic(fmt.Sprintf("A weird environ variable %q", kv))
}
- vars.Assign(kv[0], RecursiveVar{
+ vars.Assign(kv[0], &RecursiveVar{
expr: literal(kv[1]),
origin: "environment",
})
}
- vars.Assign("MAKEFILE_LIST", SimpleVar{value: []byte{}, origin: "file"})
+ vars.Assign("MAKEFILE_LIST", &SimpleVar{value: []byte{}, origin: "file"})
for _, v := range clvars {
kv := strings.SplitN(v, "=", 2)
Logf("cmdlinevar %q", kv)
if len(kv) < 2 {
panic(fmt.Sprintf("unexpected command line var %q", kv))
}
- vars.Assign(kv[0], RecursiveVar{
+ vars.Assign(kv[0], &RecursiveVar{
expr: literal(kv[1]),
origin: "command line",
})
diff --git a/serialize.go b/serialize.go
index da8b0b5..4ee0b29 100644
--- a/serialize.go
+++ b/serialize.go
@@ -321,7 +321,7 @@ func DeserializeVar(sv SerializableVar) (r Value) {
}
return e
case "varref":
- return varref{varname: DeserializeSingleChild(sv)}
+ return &varref{varname: DeserializeSingleChild(sv)}
case "paramref":
v, err := strconv.Atoi(sv.V)
if err != nil {
@@ -353,18 +353,18 @@ func DeserializeVar(sv SerializableVar) (r Value) {
return &funcNop{expr: sv.V}
case "simple":
- return SimpleVar{
+ return &SimpleVar{
value: []byte(sv.V),
origin: sv.Origin,
}
case "recursive":
- return RecursiveVar{
+ return &RecursiveVar{
expr: DeserializeSingleChild(sv),
origin: sv.Origin,
}
case ":=", "=", "+=", "?=":
- return TargetSpecificVar{
+ return &TargetSpecificVar{
v: DeserializeSingleChild(sv).(Var),
op: sv.Type,
}
diff --git a/var.go b/var.go
index 630968a..36da779 100644
--- a/var.go
+++ b/var.go
@@ -33,45 +33,45 @@ type TargetSpecificVar struct {
op string
}
-func (v TargetSpecificVar) Append(ev *Evaluator, s string) Var {
- return TargetSpecificVar{
+func (v *TargetSpecificVar) Append(ev *Evaluator, s string) Var {
+ return &TargetSpecificVar{
v: v.v.Append(ev, s),
op: v.op,
}
}
-func (v TargetSpecificVar) AppendVar(ev *Evaluator, v2 Value) Var {
- return TargetSpecificVar{
+func (v *TargetSpecificVar) AppendVar(ev *Evaluator, v2 Value) Var {
+ return &TargetSpecificVar{
v: v.v.AppendVar(ev, v2),
op: v.op,
}
}
-func (v TargetSpecificVar) Flavor() string {
+func (v *TargetSpecificVar) Flavor() string {
return v.v.Flavor()
}
-func (v TargetSpecificVar) Origin() string {
+func (v *TargetSpecificVar) Origin() string {
return v.v.Origin()
}
-func (v TargetSpecificVar) IsDefined() bool {
+func (v *TargetSpecificVar) IsDefined() bool {
return v.v.IsDefined()
}
-func (v TargetSpecificVar) String() string {
+func (v *TargetSpecificVar) String() string {
// TODO: If we add the info of |op| a test starts
// failing. Shouldn't we use this only for debugging?
return v.v.String()
// return v.v.String() + " (op=" + v.op + ")"
}
-func (v TargetSpecificVar) Eval(w io.Writer, ev *Evaluator) {
+func (v *TargetSpecificVar) Eval(w io.Writer, ev *Evaluator) {
v.v.Eval(w, ev)
}
-func (v TargetSpecificVar) Serialize() SerializableVar {
+func (v *TargetSpecificVar) Serialize() SerializableVar {
return SerializableVar{
Type: v.op,
Children: []SerializableVar{v.v.Serialize()},
}
}
-func (v TargetSpecificVar) Dump(w io.Writer) {
+func (v *TargetSpecificVar) Dump(w io.Writer) {
dumpByte(w, ValueTypeTSV)
dumpString(w, v.op)
v.v.Dump(w)
@@ -83,28 +83,28 @@ type SimpleVar struct {
origin string
}
-func (v SimpleVar) Flavor() string { return "simple" }
-func (v SimpleVar) Origin() string { return v.origin }
-func (v SimpleVar) IsDefined() bool { return true }
+func (v *SimpleVar) Flavor() string { return "simple" }
+func (v *SimpleVar) Origin() string { return v.origin }
+func (v *SimpleVar) IsDefined() bool { return true }
-func (v SimpleVar) String() string { return string(v.value) }
-func (v SimpleVar) Eval(w io.Writer, ev *Evaluator) {
+func (v *SimpleVar) String() string { return string(v.value) }
+func (v *SimpleVar) Eval(w io.Writer, ev *Evaluator) {
w.Write(v.value)
}
-func (v SimpleVar) Serialize() SerializableVar {
+func (v *SimpleVar) Serialize() SerializableVar {
return SerializableVar{
Type: "simple",
V: string(v.value),
Origin: v.origin,
}
}
-func (v SimpleVar) Dump(w io.Writer) {
+func (v *SimpleVar) Dump(w io.Writer) {
dumpByte(w, ValueTypeSimple)
dumpBytes(w, v.value)
dumpString(w, v.origin)
}
-func (v SimpleVar) Append(ev *Evaluator, s string) Var {
+func (v *SimpleVar) Append(ev *Evaluator, s string) Var {
val, _, err := parseExpr([]byte(s), nil, false)
if err != nil {
panic(err)
@@ -116,7 +116,7 @@ func (v SimpleVar) Append(ev *Evaluator, s string) Var {
return v
}
-func (v SimpleVar) AppendVar(ev *Evaluator, val Value) Var {
+func (v *SimpleVar) AppendVar(ev *Evaluator, val Value) Var {
buf := bytes.NewBuffer(v.value)
buf.WriteByte(' ')
val.Eval(buf, ev)
@@ -129,28 +129,28 @@ type RecursiveVar struct {
origin string
}
-func (v RecursiveVar) Flavor() string { return "recursive" }
-func (v RecursiveVar) Origin() string { return v.origin }
-func (v RecursiveVar) IsDefined() bool { return true }
+func (v *RecursiveVar) Flavor() string { return "recursive" }
+func (v *RecursiveVar) Origin() string { return v.origin }
+func (v *RecursiveVar) IsDefined() bool { return true }
-func (v RecursiveVar) String() string { return v.expr.String() }
-func (v RecursiveVar) Eval(w io.Writer, ev *Evaluator) {
+func (v *RecursiveVar) String() string { return v.expr.String() }
+func (v *RecursiveVar) Eval(w io.Writer, ev *Evaluator) {
v.expr.Eval(w, ev)
}
-func (v RecursiveVar) Serialize() SerializableVar {
+func (v *RecursiveVar) Serialize() SerializableVar {
return SerializableVar{
Type: "recursive",
Children: []SerializableVar{v.expr.Serialize()},
Origin: v.origin,
}
}
-func (v RecursiveVar) Dump(w io.Writer) {
+func (v *RecursiveVar) Dump(w io.Writer) {
dumpByte(w, ValueTypeRecursive)
v.expr.Dump(w)
dumpString(w, v.origin)
}
-func (v RecursiveVar) Append(_ *Evaluator, s string) Var {
+func (v *RecursiveVar) Append(_ *Evaluator, s string) Var {
var expr Expr
if e, ok := v.expr.(Expr); ok {
expr = append(e, literal(" "))
@@ -170,7 +170,7 @@ func (v RecursiveVar) Append(_ *Evaluator, s string) Var {
return v
}
-func (v RecursiveVar) AppendVar(ev *Evaluator, val Value) Var {
+func (v *RecursiveVar) AppendVar(ev *Evaluator, val Value) Var {
var buf bytes.Buffer
buf.WriteString(v.expr.String())
buf.WriteByte(' ')