Skip to content

Commit d268b35

Browse files
committed
ExtrOcamlZBigInt: Use shifts/masks to build and match positive values
This is particularly valuable for FMapPositive and other structures like stdpp's Pmap that walk a binary number's encoding, because every walk can now be done without allocation and without general-purpose division. Micro-benchmark on OCaml 5.2.1+flambda: Name Time/Run mWd/Run FMapPositive.find x100k (stock) 88.04ms 17_403_012w FMapPositive.find x100k (shift+mask) 57.32ms 6w
1 parent 2bca56e commit d268b35

1 file changed

Lines changed: 6 additions & 4 deletions

File tree

theories/extraction/ExtrOcamlZBigInt.v

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ Extraction Blacklist Z Big_int_Z.
2727
emulate the matching, see documentation of [Extract Inductive]. *)
2828

2929
Extract Inductive positive => "Big_int_Z.big_int"
30-
[ "(fun x -> Big_int_Z.succ_big_int (Big_int_Z.mult_int_big_int 2 x))"
31-
"Big_int_Z.mult_int_big_int 2" "Big_int_Z.unit_big_int" ]
30+
[ "(fun p -> Big_int_Z.succ_big_int (Big_int_Z.shift_left_big_int p 1))"
31+
"(fun p -> Big_int_Z.shift_left_big_int p 1)" "Big_int_Z.unit_big_int" ]
3232
"(fun f2p1 f2p f1 p ->
3333
if Big_int_Z.le_big_int p Big_int_Z.unit_big_int then f1 () else
34-
let (q,r) = Big_int_Z.quomod_big_int p (Big_int_Z.big_int_of_int 2) in
35-
if Big_int_Z.eq_big_int r Big_int_Z.zero_big_int then f2p q else f2p1 q)".
34+
let q = Big_int_Z.shift_right_big_int p 1 in
35+
if Big_int_Z.eq_big_int (Big_int_Z.and_big_int p Big_int_Z.unit_big_int)
36+
Big_int_Z.unit_big_int
37+
then f2p1 q else f2p q)".
3638

3739
Extract Inductive Z => "Big_int_Z.big_int"
3840
[ "Big_int_Z.zero_big_int" "" "Big_int_Z.minus_big_int" ]

0 commit comments

Comments
 (0)