5702a89db6
Since we don't need the actual split values, instead of calling `strings.Split`, which allocates new slices on each call, use `strings.Index`. This significantly reduces the allocations required when doing env value replacements. Additionally, pre-allocate the env var slice, even if we allocate a little more than we need, it keeps us from having to do multiple allocations while appending. ``` benchmark old ns/op new ns/op delta BenchmarkReplaceOrAppendEnvValues/0-8 486 313 -35.60% BenchmarkReplaceOrAppendEnvValues/100-8 10553 1535 -85.45% BenchmarkReplaceOrAppendEnvValues/1000-8 94275 12758 -86.47% BenchmarkReplaceOrAppendEnvValues/10000-8 1161268 129269 -88.87% benchmark old allocs new allocs delta BenchmarkReplaceOrAppendEnvValues/0-8 5 2 -60.00% BenchmarkReplaceOrAppendEnvValues/100-8 110 0 -100.00% BenchmarkReplaceOrAppendEnvValues/1000-8 1013 0 -100.00% BenchmarkReplaceOrAppendEnvValues/10000-8 10022 0 -100.00% benchmark old bytes new bytes delta BenchmarkReplaceOrAppendEnvValues/0-8 192 24 -87.50% BenchmarkReplaceOrAppendEnvValues/100-8 7360 0 -100.00% BenchmarkReplaceOrAppendEnvValues/1000-8 64832 0 -100.00% BenchmarkReplaceOrAppendEnvValues/10000-8 1146049 0 -100.00% ``` Signed-off-by: Brian Goff <cpuguy83@gmail.com>
43 lines
1 KiB
Go
43 lines
1 KiB
Go
package container // import "github.com/docker/docker/container"
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// ReplaceOrAppendEnvValues returns the defaults with the overrides either
|
|
// replaced by env key or appended to the list
|
|
func ReplaceOrAppendEnvValues(defaults, overrides []string) []string {
|
|
cache := make(map[string]int, len(defaults))
|
|
for i, e := range defaults {
|
|
index := strings.Index(e, "=")
|
|
cache[e[:index]] = i
|
|
}
|
|
|
|
for _, value := range overrides {
|
|
// Values w/o = means they want this env to be removed/unset.
|
|
index := strings.Index(value, "=")
|
|
if index < 0 {
|
|
// no "=" in value
|
|
if i, exists := cache[value]; exists {
|
|
defaults[i] = "" // Used to indicate it should be removed
|
|
}
|
|
continue
|
|
}
|
|
|
|
if i, exists := cache[value[:index]]; exists {
|
|
defaults[i] = value
|
|
} else {
|
|
defaults = append(defaults, value)
|
|
}
|
|
}
|
|
|
|
// Now remove all entries that we want to "unset"
|
|
for i := 0; i < len(defaults); i++ {
|
|
if defaults[i] == "" {
|
|
defaults = append(defaults[:i], defaults[i+1:]...)
|
|
i--
|
|
}
|
|
}
|
|
|
|
return defaults
|
|
}
|