diff --git a/cmd/v/internal/help/build.txt b/cmd/v/internal/help/build.txt index 94cec5896f..7c89477728 100644 --- a/cmd/v/internal/help/build.txt +++ b/cmd/v/internal/help/build.txt @@ -65,8 +65,15 @@ The build flags are shared by the build and run commands: -prod Compile the executable in production mode where most optimizations are enabled. - -prof, -profile + -prof, -profile Compile the executable with all functions profiled. + The profile results will be stored in `file.txt`. + The format is 4 fields, separated by a space, for each v function: + a) how many times it was called + b) how much *nanoseconds in total* it took + c) an average for each function (i.e. (b) / (a) ) + d) the function name + NB: if you want to output the profile info to stdout, use `-profile -`. -stats Enable more detailed statistics reporting, while compiling test files. diff --git a/cmd/v/v.v b/cmd/v/v.v index c4784633dc..b6b410f1e9 100644 --- a/cmd/v/v.v +++ b/cmd/v/v.v @@ -146,7 +146,9 @@ fn parse_args(args []string) (&pref.Preferences, string) { res.is_bare = true } '-prof', '-profile' { + res.profile_file = cmdline.option(current_args, '-profile', '-') res.is_prof = true + i++ } '-prod' { res.is_prod = true diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 3cac3a779d..9379771289 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -141,8 +141,17 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) { if is_main { if g.pref.is_prof { g.pcs_declarations.writeln('void vprint_profile_stats(){') - for pfn_name, pcounter_name in g.pcs { - g.pcs_declarations.writeln('\tif (${pcounter_name}_calls) printf("%llu %f %f ${pfn_name} \\n", ${pcounter_name}_calls, $pcounter_name, $pcounter_name / ${pcounter_name}_calls );') + if g.pref.profile_file == '-' { + for pfn_name, pcounter_name in g.pcs { + g.pcs_declarations.writeln('\tif (${pcounter_name}_calls) printf("%llu %f %f ${pfn_name} \\n", ${pcounter_name}_calls, $pcounter_name, $pcounter_name / ${pcounter_name}_calls );') + } + }else{ + g.pcs_declarations.writeln('\tFILE * fp;') + g.pcs_declarations.writeln('\tfp = fopen ("${g.pref.profile_file}", "w+");') + for pfn_name, pcounter_name in g.pcs { + g.pcs_declarations.writeln('\tif (${pcounter_name}_calls) fprintf(fp, "%llu %f %f ${pfn_name} \\n", ${pcounter_name}_calls, $pcounter_name, $pcounter_name / ${pcounter_name}_calls );') + } + g.pcs_declarations.writeln('\tfclose(fp);') } g.pcs_declarations.writeln('}') } diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index a84850d553..ddf6233236 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -31,6 +31,7 @@ pub mut: is_live bool // main program that contains live/hot code is_shared bool // an ordinary shared library, -shared, no matter if it is live or not is_prof bool // benchmark every function + profile_file string // the profile results will be stored inside profile_file translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc is_prod bool // use "-O2" obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"