The Dllist data structure doesn't keep track of the list's size, so Dllist.length ∈ Ο(n). We can speed up the function by tracking the size:
(* return number of survivor, size-tracking optimization *) (* only twice as fast *) let josephus n m = let rec j size circle = if size = 1 then Dllist.get circle else j (size-1) (Dllist.drop (Dllist.skip circle (m-1))) in let dl = Dllist.of_list (1--n) in j (Dllist.length dl) dl
This yields a factor of 2 speedup.