From 3aae63f4528ab1d7e1e12cc4e2e7bacd97991d43 Mon Sep 17 00:00:00 2001 From: "Daniel, Dao Quang Minh" Date: Tue, 11 Nov 2014 14:37:47 -0500 Subject: [PATCH] speed up creation of args and msg for huge cmds Whenever a command arguments is formed by a large linked list, repeatedly appending to arguments and displayed messages took a long time because go will have to allocate/copy a lot of times. This speeds up the allocation by preallocate arrays of correct size for args and msg Docker-DCO-1.1-Signed-off-by: Daniel, Dao Quang Minh (github: dqminh) --- builder/evaluator.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/builder/evaluator.go b/builder/evaluator.go index 645038bb1d..3f2600e29d 100644 --- a/builder/evaluator.go +++ b/builder/evaluator.go @@ -211,6 +211,21 @@ func (b *Builder) dispatch(stepN int, ast *parser.Node) error { msg += " " + ast.Value } + // count the number of nodes that we are going to traverse first + // so we can pre-create the argument and message array. This speeds up the + // allocation of those list a lot when they have a lot of arguments + cursor := ast + var n int + for cursor.Next != nil { + cursor = cursor.Next + n++ + } + l := len(strs) + strList := make([]string, n+l) + copy(strList, strs) + msgList := make([]string, n) + + var i int for ast.Next != nil { ast = ast.Next var str string @@ -218,16 +233,18 @@ func (b *Builder) dispatch(stepN int, ast *parser.Node) error { if _, ok := replaceEnvAllowed[cmd]; ok { str = b.replaceEnv(ast.Value) } - strs = append(strs, str) - msg += " " + ast.Value + strList[i+l] = str + msgList[i] = ast.Value + i++ } + msg += " " + strings.Join(msgList, " ") fmt.Fprintln(b.OutStream, msg) // XXX yes, we skip any cmds that are not valid; the parser should have // picked these out already. if f, ok := evaluateTable[cmd]; ok { - return f(b, strs, attrs, original) + return f(b, strList, attrs, original) } fmt.Fprintf(b.ErrStream, "# Skipping unknown instruction %s\n", strings.ToUpper(cmd))