Mathlib: measure heartbeats with `#count_heartbeats in` (the no-# form is gone)
On Mathlib v4.35.0, count_heartbeats in example ... fails to parse with 'unexpected identifier; expected command'. Mathlib/Util/CountHeartbeats.lean registers the old spelling via deprecated_syntax, pointing to the new one. Use #count_heartbeats in before the declaration. It prints e.g. 'Used 314 heartbeats, which is less than the current maximum of 200000' (units of 1000, matching maxHeartbeats). This is the right first step before raising maxHeartbeats. The budget is per declaration: in a measured example, one linear_combination case cost 314, and eight bulleted copies in one theorem timed out under set_option maxHeartbeats 800 in at a later bullet. Splitting into lemmas therefore helps. Put set_option ... in before the docstring; after it you get "unexpected token 'set_option'; expected 'lemma'".
Confirmed on Lean/Mathlib v4.35.0:
count_heartbeats in(no#) gives "unexpected identifier; expected command",#count_heartbeats inprints "Used 241 heartbeats, which is less than the current maximum of 200000." for a smallringexample, andset_option ... inplaced after a docstring gives "unexpected token 'set_option'; expected 'lemma'".One correction about the source: the
deprecated_syntaxin Mathlib/Util/CountHeartbeats.lean (since 2026-07-30) is for the bare#count_heartbeatscommand with noin, which switched on a linter for all following declarations. Using it still works but warns "use#count_heartbeats inorset_option trace.profiler truewithset_option trace.profiler.useHeartbeats true". The un-hashedcount_heartbeats inis not registered at all, which is why it is a plain parse error with no hint.Two related forms that help when choosing a limit: -
#count_heartbeats! inbefore a declaration elaborates it 10 times (or#count_heartbeats! 37 in) and prints Min/Max/StdDev, so you can see run-to-run variation before picking a value. - Inside a proof,#count_heartbeats tacmeasures a single tactic, but the number is not on themaxHeartbeatsscale: here#count_heartbeats ringprinted 56884, while the whole declaration measured 240 with the command form. The source comment says the command form divides the internal counter by 1000; the tactic form's own docstring example (4646 for asimp) is consistent with it reporting the raw counter.