Skip to content

feat(cli): add --time flag to report script execution timing#4711

Merged
jedel1043 merged 8 commits intoboa-dev:mainfrom
Nakshatra480:feature/cli-time-flag
Feb 28, 2026
Merged

feat(cli): add --time flag to report script execution timing#4711
jedel1043 merged 8 commits intoboa-dev:mainfrom
Nakshatra480:feature/cli-time-flag

Conversation

@Nakshatra480
Copy link
Contributor

Summary

This adds a --time flag to the Boa CLI that prints how long parsing and execution took, similar to what other engines offer (V8's d8 --times, etc.).

When the flag is passed, timing info is printed to stderr so it doesn't interfere with script output on stdout:
$ boa --time script.js Hello, World!
Execution: 1.56ms

For modules, parsing and execution are measured separately:
$ boa --time -m module.mjs 42
Parsing: 1.82ms Execution: 1.27ms Total: 3.09ms

Without the flag, there's zero overhead — no Instant::now() calls and no extra output.

Changes

All changes are in cli/src/main.rs:

  • Added --time boolean flag to the Opt struct (long flag only, since -t is already used by --trace)
  • Wrapped context.eval() in evaluate_expr and evaluate_file with conditional Instant measurements using args.time.then(Instant::now)
  • For the module path, Module::parse() and load_link_evaluate() are measured separately
  • In evaluate_expr, context.run_jobs() is called unconditionally after eval so async work is always drained regardless of whether timing is enabled

No new dependencies - uses std::time::Instant which was already imported (as Duration) in the file.

Closes #4709

@codecov
Copy link

codecov bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 0% with 85 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.05%. Comparing base (6ddc2b4) to head (3edfe6d).
⚠️ Report is 704 commits behind head on main.

Files with missing lines Patch % Lines
cli/src/main.rs 0.00% 85 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4711      +/-   ##
==========================================
+ Coverage   47.24%   57.05%   +9.81%     
==========================================
  Files         476      552      +76     
  Lines       46892    60568   +13676     
==========================================
+ Hits        22154    34559   +12405     
- Misses      24738    26009    +1271     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

github-actions bot commented Feb 25, 2026

Test262 conformance changes

Test result main count PR count difference
Total 52,862 52,862 0
Passed 49,505 49,505 0
Ignored 2,261 2,261 0
Failed 1,096 1,096 0
Panics 0 0 0
Conformance 93.65% 93.65% 0.00%

@jedel1043 jedel1043 added enhancement New feature or request cli Issues and PRs related to the Boa command line interface. waiting-on-review Waiting on reviews from the maintainers labels Feb 25, 2026
@Nakshatra480 Nakshatra480 requested a review from a team as a code owner February 26, 2026 19:11
@Nakshatra480
Copy link
Contributor Author

Hey @jedel1043 just following up here 🙂

This adds a --time flag to the Boa CLI that prints parsing and execution timings to stderr (so it won’t mix with script stdout).

It measures parse vs. execution separately for modules and has no runtime overhead when the flag isn’t used.

Would appreciate a review from someone on the CLI/runtime side, happy to make any changes if needed.

Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I have a very small suggestion.

@jedel1043 jedel1043 added waiting-on-author Waiting on PR changes from the author and removed waiting-on-review Waiting on reviews from the maintainers labels Feb 27, 2026
@Nakshatra480 Nakshatra480 marked this pull request as draft February 27, 2026 20:36
@Nakshatra480 Nakshatra480 marked this pull request as ready for review February 27, 2026 22:59
@jedel1043
Copy link
Member

jedel1043 commented Feb 27, 2026

I kinda feel like this pattern of start = now, then executing something and elapsed = time can probably be simplified with a couple of structs:

struct Timer<'a> {
    name: &'static str,
    now: Instant,
    counters: &'a mut Vec<(&'static str, Duration)>
}

impl Drop for Timer<'a> {
    fn drop(&mut self) {
        self.counters.push((self.name, self.now.elapsed()));
    }
}


struct Counters {
    counters: Option<Vec<(&'static str, Duration)>>
}

impl Counters {
    fn new_timer(&mut self, name: &'static str) -> Option<Timer<'_>> {
        if let Some(counters) = &mut self.counters {
            Some(Timer {
              name,
              now: Instant::now(),
              counters
            })
        } else { None }
        
    }
}

impl Drop for Counters {
    // Code to print all timers
}

That way, to measure something you just do like

{
    let _timer = counters.new_timer("Parsing");
    // parse
}

// more code

@Nakshatra480 Nakshatra480 marked this pull request as draft February 28, 2026 01:04
@Nakshatra480 Nakshatra480 marked this pull request as ready for review February 28, 2026 12:55
@Nakshatra480
Copy link
Contributor Author

Hey @jedel1043, thanks again for the review and the suggestions.

I’ve just pushed some updates to address your feedback:

  • Timer & Counters struct: Implemented your suggestion! This makes the code super clean and ensures there's zero overhead when the flag isn't passed (we just use an Option and don't create Instants).
  • Split timings everywhere: The timing is now consistently split into Parsing and Execution (or AST generation for --dump-ast) across all execution paths (module, script, and expression).
  • Avoided print overhead: Moved print_timing() to happen completely independently from result/error printing, so we aren't measuring console I/O time anymore. I also made sure that async job execution (run_jobs()) is accurately included in the execution timer for consistency.
  • Fixed -t flag conflict: Also noticed that the short -t flag was accidentally reassigned from --trace to --time in the previous iteration. I’ve reverted that so --trace keeps its short flag, avoiding any breaking changes there.

Let me know if this looks good to you or if there's anything else you'd like me to tweak!

@Nakshatra480 Nakshatra480 marked this pull request as draft February 28, 2026 16:15
@Nakshatra480 Nakshatra480 marked this pull request as ready for review February 28, 2026 16:19
Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice work! Thank you!

@jedel1043 jedel1043 enabled auto-merge February 28, 2026 16:23
@jedel1043 jedel1043 added this pull request to the merge queue Feb 28, 2026
Merged via the queue into boa-dev:main with commit db19e4e Feb 28, 2026
19 checks passed
@Nakshatra480 Nakshatra480 deleted the feature/cli-time-flag branch February 28, 2026 16:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli Issues and PRs related to the Boa command line interface. enhancement New feature or request waiting-on-author Waiting on PR changes from the author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Add --time CLI flag to report script execution timing

2 participants