aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Nigmatzianov <[email protected]>2017-04-05 10:32:46 +0200
committerAlbert Nigmatzianov <[email protected]>2017-04-05 17:46:54 +0200
commit0328f159d6f2cbe8b87468ff88f631b0d4d16953 (patch)
treec2a04f9ef9883a016be23c56282484f70a964bc8
parent9a906f17374922ed0f74e1b2f593d3723f2ffb00 (diff)
Cache sorted flags
As you can't delete flags in FlagSet, this method works Gainful performance improvement: benchmark old ns/op new ns/op delta BenchmarkVisitAll10Flags-4 1549 33.9 -97.81% BenchmarkVisit10Flags-4 1704 34.2 -97.99% benchmark old allocs new allocs delta BenchmarkVisitAll10Flags-4 3 0 -100.00% BenchmarkVisit10Flags-4 3 0 -100.00% benchmark old bytes new bytes delta BenchmarkVisitAll10Flags-4 272 0 -100.00% BenchmarkVisit10Flags-4 272 0 -100.00%
-rw-r--r--flag.go21
1 files changed, 19 insertions, 2 deletions
diff --git a/flag.go b/flag.go
index 3a2e255..2bfedff 100644
--- a/flag.go
+++ b/flag.go
@@ -142,8 +142,10 @@ type FlagSet struct {
parsed bool
actual map[NormalizedName]*Flag
orderedActual []*Flag
+ sortedActual []*Flag
formal map[NormalizedName]*Flag
orderedFormal []*Flag
+ sortedFormal []*Flag
shorthands map[byte]*Flag
args []string // arguments after flags
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
@@ -200,6 +202,7 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
// "--getUrl" which may also be translated to "geturl" and everything will work.
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
f.normalizeNameFunc = n
+ f.sortedFormal = f.sortedFormal[:0]
for k, v := range f.orderedFormal {
delete(f.formal, NormalizedName(v.Name))
nname := f.normalizeFlagName(v.Name)
@@ -240,9 +243,16 @@ func (f *FlagSet) SetOutput(output io.Writer) {
// in primordial order if f.SortFlags is false, calling fn for each.
// It visits all flags, even those not set.
func (f *FlagSet) VisitAll(fn func(*Flag)) {
+ if len(f.formal) == 0 {
+ return
+ }
+
var flags []*Flag
if f.SortFlags {
- flags = sortFlags(f.formal)
+ if len(f.formal) != len(f.sortedFormal) {
+ f.sortedFormal = sortFlags(f.formal)
+ }
+ flags = f.sortedFormal
} else {
flags = f.orderedFormal
}
@@ -279,9 +289,16 @@ func VisitAll(fn func(*Flag)) {
// in primordial order if f.SortFlags is false, calling fn for each.
// It visits only those flags that have been set.
func (f *FlagSet) Visit(fn func(*Flag)) {
+ if len(f.actual) == 0 {
+ return
+ }
+
var flags []*Flag
if f.SortFlags {
- flags = sortFlags(f.actual)
+ if len(f.actual) != len(f.sortedActual) {
+ f.sortedActual = sortFlags(f.actual)
+ }
+ flags = f.sortedActual
} else {
flags = f.orderedActual
}