The usual cause is having a UFL form which contains a rapidly-changing floating point number.
This is fine:
solve(inner(grad(u), grad(v))*dx = 2.0*f*v*dx, out, ...) # solve -div(grad(u)) = 2*f just once
This is a bad idea:
t = 0.0; T = 500.0; dt = 0.1
while t < T:
solve(inner(grad(u), grad(v))*dx = sin(t)*f*v*dx, out, ...) # multiply forcing by sin(t)
t += dt
This would generate and compile 5000 different C files, with the values t = 0.0, 0.1, 0.2, 0.3, ... each "hardcoded" into the C code of one form.
A better solution is to use a Constant object inside the form, and update this within the loop:
t = 0.0; T = 500.0; dt = 0.1
tc = Constant(t)
while t < T:
solve(inner(grad(u), grad(v))*dx = sin(tc)*f*v*dx, out, ...) # multiply forcing by sin(t)
t += dt
tc.assign(t)
This will generate a single compiled form where the current time is passed in via a pointer, rather than being hardcoded into the C code.
Note: if you are repeatedly solving a problem like this, it's a bit better to use the LinearVariationalProblem/LinearVariationalSolver objects, as described at
https://www.firedrakeproject.org/demos/DG_advection.py.html, but this is ultimately separate to Constant vs hard-coded floating point numbers.