-
Notifications
You must be signed in to change notification settings - Fork 4
ALL_CAPS are now constants. Changed/shared recursive function environment. Fixed bug with macro environment. Added pprof. #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
113c299
ce37333
05bf8b9
ac2a440
fcb5f1f
43f20dc
6be89df
3973284
efe013f
542cc2d
b0260c1
55a8a1e
60a4899
9b8635a
2d03d45
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // Keep 0.24 syntax for perf comparison. Used to detect a serious performance regression | ||
| // during https://github.com/grol-io/grol/pull/102 | ||
| f = func(i, n, prod) { | ||
| if (i == n+1) { | ||
| return 1. / (prod * prod * n) | ||
| } | ||
| f(i+1, n, prod*(1-1./(2*i))) | ||
| } | ||
| n = 100000 | ||
| f(1, n, 1) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,11 +5,13 @@ import ( | |
| "flag" | ||
| "fmt" | ||
| "os" | ||
| "runtime/pprof" | ||
|
|
||
| "fortio.org/cli" | ||
| "fortio.org/log" | ||
| "grol.io/grol/eval" | ||
| "grol.io/grol/extensions" // register extensions | ||
| "grol.io/grol/object" | ||
| "grol.io/grol/repl" | ||
| ) | ||
|
|
||
|
|
@@ -24,6 +26,9 @@ func Main() int { | |
| compact := flag.Bool("compact", false, "When printing code, use no indentation and most compact form") | ||
| showEval := flag.Bool("eval", true, "show eval results") | ||
| sharedState := flag.Bool("shared-state", false, "All files share same interpreter state (default is new state for each)") | ||
| cpuprofile := flag.String("profile-cpu", "", "write cpu profile to `file`") | ||
| memprofile := flag.String("profile-mem", "", "write memory profile to `file`") | ||
|
|
||
| cli.ArgsHelp = "*.gr files to interpret or `-` for stdin without prompt or no arguments for stdin repl..." | ||
| cli.MaxArgs = -1 | ||
| cli.Main() | ||
|
|
@@ -34,9 +39,22 @@ func Main() int { | |
| FormatOnly: *format, | ||
| Compact: *compact, | ||
| } | ||
|
|
||
| if *cpuprofile != "" { | ||
| f, err := os.Create(*cpuprofile) | ||
| if err != nil { | ||
| log.Fatalf("can't open file for cpu profile: %v", err) | ||
| } | ||
| err = pprof.StartCPUProfile(f) | ||
| if err != nil { | ||
| log.Fatalf("can't start cpu profile: %v", err) | ||
| } | ||
| log.Infof("Writing cpu profile to %s", *cpuprofile) | ||
| defer pprof.StopCPUProfile() | ||
| } | ||
| err := extensions.Init() | ||
| if err != nil { | ||
| log.Fatalf("Error initializing extensions: %v", err) | ||
| return log.FErrf("Error initializing extensions: %v", err) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So FErrf is Fatalf ? The name could be better
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's same level as fatal but doesn't try to exit, returns non 0 instead which lets defer run and also make linters happy (and works well with main() {os.Exit(Main())} which lets testscript work well too)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why using your ferry here, and using Fatalf in previous if block you add
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ic you mean why not change all of them, so far I only changed what the linter complained about re defer not to running but probably should be all yes, in theory/for consistency
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. of note there are still a few more log.Fatalf in other functions (like if you fail to pass a valid filename) and it's fine... for now at least (just means some pprof defer won't happen) |
||
| } | ||
| if *commandFlag != "" { | ||
| res, errs, _ := repl.EvalString(*commandFlag) | ||
|
|
@@ -52,19 +70,31 @@ func Main() int { | |
| } | ||
| options.All = true | ||
| s := eval.NewState() | ||
| macroState := eval.NewState() | ||
| macroState := object.NewMacroEnvironment() | ||
| for _, file := range flag.Args() { | ||
| processOneFile(file, s, macroState, options) | ||
| if !*sharedState { | ||
| s = eval.NewState() | ||
| macroState = eval.NewState() | ||
| macroState = object.NewMacroEnvironment() | ||
| } | ||
| } | ||
| log.Infof("All done") | ||
| if *memprofile != "" { | ||
| f, err := os.Create(*memprofile) | ||
| if err != nil { | ||
| return log.FErrf("can't open file for mem profile: %v", err) | ||
| } | ||
| err = pprof.WriteHeapProfile(f) | ||
| if err != nil { | ||
| return log.FErrf("can't write mem profile: %v", err) | ||
| } | ||
| log.Infof("Wrote memory profile to %s", *memprofile) | ||
| f.Close() | ||
| } | ||
| return 0 | ||
| } | ||
|
|
||
| func processOneFile(file string, s, macroState *eval.State, options repl.Options) { | ||
| func processOneFile(file string, s *eval.State, macroState *object.Environment, options repl.Options) { | ||
| if file == "-" { | ||
| if options.FormatOnly { | ||
| log.Infof("Formatting stdin") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could add a map[type]func(Node) Object
Then you create one method per type
So evalInternal method will then simply check if there is a func, then call it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about this?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the reminder, I had skipped that one earlier
If it worked, we'd need to profile it (good that there is
-profile-cpunow) but I don't think it'd help because you'd need to cast anyway inside each small function (but try and let me know :) ?)Note that for other types, like token.Type or object.Type an array lookup would be good, as the type fit into uint8 which eliminates bound checks, and I had started something like that in #93