Zulip Chat Archive
Stream: mathlib4
Topic: Measure is overloaded
Floris van Doorn (Jun 15 2023 at 18:05):
The following example is bad:
import Mathlib.MeasureTheory.Measure.MeasureSpaceDef
open MeasureTheory
set_option profiler true
set_option trace.profiler true
set_option trace.Meta.synthInstance true
-- the following line takes 2+ seconds to compile
variable {α : Type _} [MeasurableSpace α] (μ μ₁ μ₂ μ₃ μ₄ μ₅ : Measure α)
variable (α) -- this also takes 2+ seconds to compile
-- every command in this file will take 2 extra seconds to compile
The problem is that docs4#MeasureTheory.Measure is overloaded with docs4#Measure, and for every variable it now attempts an (expensive and failing) type-class problem to find a coercion from Type ?u.2
(the type of α
) to ?m.10 → ℕ
(the type of the first argument of Measure
). Note that variables are recompiled for every new variable
/def
/theorem
/... so this file will probably get very slow
We hit this in !4#4929, but I expect this is a major slowdown in all files using measures.
What should we do to fix this? We should probably do multiple of the following list:
(1) As a temporary workaround, write MeasureTheory.Measure
in a lot of places (especially variable
commands) instead of Measure
(2) Move Measure
to a namespace (Nat.Measure
?)
(3) Cache type-class failures in this case
(4) Have a precached failure that Type _
will not coerce to any function (or anything else, probably).
(5) Have x : _root_.Measure α
fail without doing any type-class inference: _root_.Measure _
will have type _ → _ → Prop
which should never match with Sort _
(I'm very happy if we disallow coercions like this - assuming that we can keep the coercion Set _ >-> Type _
)
Oliver Nash (Jun 15 2023 at 18:14):
Wow, great find. I definitely support 2, probably also 3--5, and maybe even 1. Who can action this?
Floris van Doorn (Jun 15 2023 at 18:22):
Continuing the example:
-- takes ~2.5s to compile (since it also parses variables)
example : 1 = 1 := rfl
-- takes ~10s to compile, apparently it parses all the variables 4 times?
notation:67 f " ⋆ " => id f
Is it intended that the notation
command parses the variable list 4 separate times (at least, that's what seems to be happening)?
Floris van Doorn (Jun 15 2023 at 18:31):
!4#4929 takes 5m 46s to build using Measure
and 1m 50s to build using MeasureTheory.Measure
.
Sebastian Ullrich (Jun 15 2023 at 18:34):
Floris van Doorn said:
Is it intended that the
notation
command parses the variable list 4 separate times (at least, that's what seems to be happening)?
That's an "interesting" side effect of notation
expanding into multiple primitive declarations
Floris van Doorn (Jun 15 2023 at 18:39):
Of course, the slowdown would be greatly mitigated by
(6) do not re-elaborate the variables for every command
but I don't know the reasons for the Lean 4 behavior of the variable command, so this option might be bad.
Sebastian Ullrich (Jun 15 2023 at 18:44):
I may be responsible for suggesting "variables should just be inserted syntactically, like macros!" in order to avoid all our problems with them in Lean 3. Now we have new problems...
Floris van Doorn (Jun 15 2023 at 20:44):
In !4#5100 I changed all occurences in variable
lines. I think that will already have a big impact, and this PR can be used to measure how big. lean4#2275 implements option (2).
Last updated: Dec 20 2023 at 11:08 UTC