Zulip Chat Archive

Stream: general

Topic: Slow elaboration using Submodule.span and struct field


Aaron Hill (Jan 02 2025 at 11:03):

In the following code, elaboration takes ~12 seconds in Lean 4 Web:

import Mathlib.Analysis.Normed.Module.Basic
import Mathlib.LinearAlgebra.Finsupp.VectorSpace

set_option trace.profiler true

structure MySpans where
  struct_val: 
  const_arg: Submodule.span  { (Finsupp.single 1 1 : ( →₀ )) }
  struct_arg: Submodule.span  { (Finsupp.single struct_val 1 : ( →₀ )) }

with the trace:

[Elab.command] [12.224461] structure MySpans where
      struct_val : 
      const_arg : Submodule.span  {(Finsupp.single 1 1 : ( →₀ ))}
      struct_arg : Submodule.span  {(Finsupp.single struct_val 1 : ( →₀ ))} 
  [step] [0.019285] expected type: Sort ?u.6, term
    Submodule.span  {(Finsupp.single 1 1 : ( →₀ ))}
  [Meta.sizeOf] [0.024981] MySpans
  [Meta.injective] [0.031896] MySpans.mk

If I comment out struct_arg, elaboration takes ~0.1 seconds.
Why does this take so long to elaborate?

Eric Wieser (Jan 02 2025 at 11:13):

Even this is slow:

import Mathlib.Analysis.Normed.Module.Basic
import Mathlib.LinearAlgebra.Finsupp.VectorSpace

-- elaborate this up-front, which is fast
def s (n : ) : Type _ := Submodule.span  {(Finsupp.single struct_val 1 : ( →₀ ))}

suppress_compilation
set_option trace.profiler true

structure MySpans where
  struct_val: 
  struct_arg: s struct_val

Eric Wieser (Jan 02 2025 at 11:15):

Changing def to opaque makes it instant

Kevin Buzzard (Jan 04 2025 at 09:29):

For the latter code I currently get unknown identifier 'struct_val', presumably there is a typo somewhere. For the former it's also slow for me. Furthermore the timings don't add up, which is something I never understood.

Eric Wieser (Jan 04 2025 at 14:12):

Timings not adding up is expected, it corresponds to something like the pseudocode

def foo := time "foo" do
  time "a" doA
  time "b" doB
  doC
  time "d" doD

which will not create any subtiming for doC

Eric Wieser (Jan 04 2025 at 14:12):

But of course this suggests Lean should add another timing block for whatever is not being categorized here

Eric Wieser (Jan 04 2025 at 14:13):

See #19855 for an example of real code doing this

Aaron Hill (Jan 04 2025 at 14:33):

I think the definition of s is supposed to be def s (n : ℕ) : Type _ := Submodule.span ℚ {(Finsupp.single n 1 : (ℕ →₀ ℚ))}


Last updated: May 02 2025 at 03:31 UTC