Skip to content

Commit

Permalink
Add some useful benchmarks (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
FollowTheProcess authored Aug 5, 2024
1 parent 23f5ae3 commit 7df5b31
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 1 deletion.
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Things I want to do to make this library as good as it can be and a better, simp
- [x] Rename `cmd.example` to `cmd.examples`
- [x] Clean up/rewrite some of the functions borrowed from Cobra e.g. `argsMinusFirstX`
- [ ] Clean up and optimise the parsing logic
- [ ] Do some benchmarking and see where we can improve
- [x] Do some benchmarking and see where we can improve
- [x] Remove the `Loop` tag from parsing functions
- [ ] More full test programs as integration tests
- [ ] Write a package example doc
Expand Down
53 changes: 53 additions & 0 deletions command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
goflag "flag"
"fmt"
"io"
"os"
"path/filepath"
"slices"
Expand Down Expand Up @@ -626,3 +627,55 @@ func TestExecuteNonRootCommand(t *testing.T) {
test.Equal(t, err.Error(), "Execute must be called on the root of the command tree, was called on sub")
}
}

func BenchmarkExecuteHelp(b *testing.B) {
sub1, err := cli.New(
"sub1",
cli.Short("Do one thing"),
cli.Run(func(cmd *cli.Command, args []string) error {
fmt.Fprintln(cmd.Stdout(), "Hello from sub1")
return nil
}),
)
test.Ok(b, err)

sub2, err := cli.New(
"sub2",
cli.Short("Do another thing"),
cli.Run(func(cmd *cli.Command, args []string) error {
fmt.Fprintln(cmd.Stdout(), "Hello from sub2")
return nil
}),
)
test.Ok(b, err)

sub3, err := cli.New(
"very-long-subcommand",
cli.Short("Wow so long"),
cli.Run(func(cmd *cli.Command, args []string) error {
fmt.Fprintln(cmd.Stdout(), "Hello from sub3")
return nil
}),
)
test.Ok(b, err)

cmd, err := cli.New(
"bench-help",
cli.Short("A helpful benchmark command"),
cli.Long("Much longer text..."),
cli.Example("Do a thing", "bench-help very-long-subcommand --flag"),
cli.SubCommands(sub1, sub2, sub3),
cli.Args([]string{"--help"}),
cli.Stderr(io.Discard),
cli.Stdout(io.Discard),
)
test.Ok(b, err)

b.ResetTimer()
for range b.N {
err := cmd.Execute()
if err != nil {
b.Fatalf("Execute returned an error: %v", err)
}
}
}
14 changes: 14 additions & 0 deletions internal/flag/flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -648,3 +648,17 @@ func TestFlagNilSafety(t *testing.T) {
test.Equal(t, err.Error(), "cannot set value true, flag.value was nil")
})
}

func BenchmarkFlagSet(b *testing.B) {
var count int
flag, err := flag.New(&count, "count", 'c', 0, "Count things")
test.Ok(b, err)

b.ResetTimer()
for range b.N {
err := flag.Set("42")
if err != nil {
b.Fatalf("flag.Set returned an error: %v", err)
}
}
}
31 changes: 31 additions & 0 deletions internal/flag/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1205,3 +1205,34 @@ func TestUsage(t *testing.T) {
})
}
}

func BenchmarkParse(b *testing.B) {
set := flag.NewSet()
f, err := flag.New(new(int), "count", 'c', 0, "Count something")
test.Ok(b, err)

f2, err := flag.New(new(bool), "delete", 'd', false, "Delete something")
test.Ok(b, err)

f3, err := flag.New(new(string), "name", 'n', "", "Name something")
test.Ok(b, err)

err = flag.AddToSet(set, f)
test.Ok(b, err)

err = flag.AddToSet(set, f2)
test.Ok(b, err)

err = flag.AddToSet(set, f3)
test.Ok(b, err)

args := []string{"some", "args", "here", "--delete", "--count", "10", "--name", "John"}

b.ResetTimer()
for range b.N {
err := set.Parse(args)
if err != nil {
b.Fatalf("Parse returned an error: %v", err)
}
}
}

0 comments on commit 7df5b31

Please sign in to comment.