
The search token preprocessing was taking quadratic time.

After fixing that, I special-cased n=1..4 with a per-char search for n=1 and PCRE for n=2..4.

Now it is nice and fast.
art with code
let reverse l =
let rec aux res l = match l with
| [] -> res
| (h::t) -> aux (h::res) t in
aux [] l
(**Q
(Q.list_of_size (fun () -> Random.int 2) Q.int) (fun l -> reverse l = l)
(Q.list Q.int) (fun l -> reverse (reverse l) = l)
(* Thanks to notfancy on reddit for the following law. *)
(* Demonstrating tuple generation *)
(Q.pair (Q.list Q.int) (Q.list Q.int)) (fun (l,m) -> reverse (l @ m) = reverse m @ reverse l)
**)
open OUnit
module Q = Quickcheck
open Reverse
let _iteri f l = ignore (List.fold_left (fun i v -> f v i; i + 1) 0 l)
let _TL = _iteri (fun (n,b) i ->
OUnit.assert_bool ("Line " ^ string_of_int (i+1) ^ " of bool test: " ^ n) b)
let test_reverse_line_6 () =
Quickcheck.laws_exn
"(Q.list_of_size (fun () -> Random.int 2) Q.int) (fun l -> reverse l = l)"
(Q.list_of_size (fun () -> Random.int 2) Q.int) (fun l -> reverse l = l);
Quickcheck.laws_exn
"(Q.list Q.int) (fun l -> reverse (reverse l) = l)"
(Q.list Q.int) (fun l -> reverse (reverse l) = l);
(* Thanks to notfancy on reddit for the following law. *)
(* Demonstrating tuple generation *)
Quickcheck.laws_exn
"(Q.pair (Q.list Q.int) (Q.list Q.int)) (fun (l,m) -> reverse (l @ m) = reverse m @ reverse l)"
(Q.pair (Q.list Q.int) (Q.list Q.int)) (fun (l,m) -> reverse (l @ m) = reverse m @ reverse l);()
let suite = "Reverse unit tests" >:::
[
"test_reverse_line_6" >:: test_reverse_line_6
]
let () = Tests.register suite
let reverse l =
let rec aux res l = match l with
| [] -> res
| (h::t) -> aux (h::res) t in
aux [] l
(***
(* embedded test body *)
assert_equal (reverse []) [];
assert_equal (reverse [1]) [1];
assert_equal (reverse (1--10)) (10--1)
**)
(**T
(* embedded boolean test list *)
reverse [] = []
reverse [1] = [1]
reverse (1--10) = (10--1)
**)
(**Q
(* embedded QuickCheck law list *)
Q.list ~size_gen:(fun _ -> Random.int 2) Q.uig (fun l -> reverse l = l)
Q.list Q.uig (fun l -> reverse (reverse l) = l)
Q.list Q.uig (fun l -> reverse l = list (areverse (array l)))
Q.list Q.cg (fun l -> reverse l = explode (sreverse (implode l)))
**)
let shell_escape =
let re = Pcre.regexp "(?=[^a-zA-Z0-9._+/-])" in
Pcre.replace ~rex:re ~templ:"\\"
(**Q
Q.uint (fun i -> shell_escape (string_of_int i) = (string_of_int i))
Q.string (fun s -> slen (shell_escape s) = slen s)
**)
law Q.string (fun s -> slen (shell_escape s) = slen s) failed for
"\018\235\220\202U\222\146\200\002\249\232\170\015\238\147\238\004
\209\003\241\182\245\150\t\016P\190"
FAIL: Unit tests:0:Prelude unit tests:671:test_prelude_line_8631
OUnit: Line 5 of bool test: shell_escape "foo is fan/cy+some!" = "foo\\ is\\ fan/cy+some!"