Created
March 15, 2017 18:28
-
-
Save mandarjog/daee012c5c973fecd106f49c786f96cc to your computer and use it in GitHub Desktop.
slice allocation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func (f *Function) Eval(attrs attribute.Bag, fMap map[string]Func) (interface{}, error) { | |
fn := fMap[f.Name] | |
if fn == nil { | |
return nil, fmt.Errorf("unknown function: %s", f.Name) | |
} | |
if ufn, ok := fn.(UnmanagedFunc); ok { | |
return ufn.CallUnmanaged(attrs, f.Args, fMap) | |
} | |
// may panic if config is not consistent with Func.ArgTypes(). | |
s := AllocSlice() | |
//args := make([]interface{}, len(f.Args), len(f.Args)) | |
args := s.s[0:len(f.Args)] | |
for idx, earg := range f.Args { | |
arg, err := earg.Eval(attrs, fMap) | |
if err != nil && !fn.AcceptsNulls() { | |
return nil, err | |
} | |
args[idx] = arg | |
} | |
if glog.V(2) { | |
glog.Infof("calling %#v %#v", fn, args) | |
} | |
ret := fn.Call(args) | |
FreeSlice(s) | |
return ret, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think you said you tried something like
and didn't notice an improvement, right?
I'm guessing that's because when the compiler sees
ret := fn.Call(args)
it can't be sure that args won't escape, so it must do some heap allocation there. (Note that if args had a stack-allocated argbuf as backing array and it did escape, and Eval returned, then args would point to garbage.)As far as I can see, using a sync.Pool is a good choice.
If there's no concurrency in this language, then maybe another approach is to have a stack of args. Or maybe one large array
and a "stack pointer" saying where the next free spot is. You'd be trading the cost of allocating arg slices for the up-front cost of a large static allocation.