Skip to content

Slowness of `set_unfold` for `gset`

This issue follows up on iris#232 (closed).

It appears that set_unfold is very slow on goals involving gset. For example, when calling set_unfold on a goal like the following, it takes near half a second.

Lemma slow `{Countable K} (X1 X2 X3 : gset K) :
  X1  (X2  X3) = (X1  X2)  X3.

Interestingly enough, the problem does not appear in the following goal, where set_unfold takes close to no time:

Lemma fast `{FinSet K C, !LeibnizEquiv C} (X1 X2 X3 : C) :
  X1  (X2  X3) = (X1  X2)  X3.

So, clearly set_unfold is doing inefficient things in combination with gset.

After a bit of trial and error, it appears that the elem_of operation on gset is the culprit. Type class search, as used in the implementation of set_unfold tries to unfold stuff there. If I make elem_of type class opaque, the performance improves significantly.

I tried a bunch of stuff:

Some experiments

From stdpp Require Import gmap.

Lemma fast `{FinSet K C, !LeibnizEquiv C} (X1 X2 X3 : C) :
  X1  (X2  X3) = (X1  X2)  X3.
Proof.
  Time set_unfold.
  (* Finished transaction in 0.032 secs (0.031u,0.s) (successful) *)
Abort.

Lemma slow `{Countable K} (X1 X2 X3 : gset K) :
  X1  (X2  X3) = (X1  X2)  X3.
Proof.
  Time set_unfold.
  (* Finished transaction in 0.382 secs (0.373u,0.s) (successful) *)
Restart.
  Typeclasses Opaque elem_of.
  Time set_unfold.
  (* Finished transaction in 0.03 secs (0.029u,0.s) (successful) *)
  Typeclasses Transparent elem_of. (* undo *)
Restart.
  Typeclasses Opaque gset_elem_of.
  Time set_unfold.
  (* Finished transaction in 0.253 secs (0.252u,0.s) (successful) *)
Restart.
  Typeclasses Opaque mapset.mapset_elem_of.
  Time set_unfold.
  (* Finished transaction in 0.366 secs (0.357u,0.s) (successful)
     WTF this is even slower? *)
Admitted.

Lemma fast_big `{FinSet K C, !LeibnizEquiv C} (X1 X2 X3 : C) :
  X1  (X2  X3)  X1  X2  X1  (X2  X3)  X1  X2 =
  X1  X2  X3  X1  X2  X1  (X2  X3)  X1  X2 
  X1  X2  X3  X1  X2  X1  (X2  X3)  X1  X2.
Proof.
  Time set_unfold.
  (* Finished transaction in 0.135 secs (0.131u,0.s) (successful) *)
Admitted.

Lemma slow_big `{Countable K} (X1 X2 X3 : gset K) :
  X1  (X2  X3)  X1  X2  X1  (X2  X3)  X1  X2 =
  X1  X2  X3  X1  X2  X1  (X2  X3)  X1  X2 
  X1  X2  X3  X1  X2  X1  (X2  X3)  X1  X2.
Proof.
  Time set_unfold.
  (* Finished transaction in 1.839 secs (1.836u,0.004s) (successful) *)
Restart.
  Typeclasses Opaque elem_of.
  Time set_unfold.
  (* Finished transaction in 0.157 secs (0.148u,0.s) (successful) *)
Admitted.
Edited by Robbert Krebbers