diff --git a/_oasis b/_oasis index 1e942b52..437da1e2 100644 --- a/_oasis +++ b/_oasis @@ -155,7 +155,7 @@ Executable run_benchs CompiledObject: best Build$: flag(bench) MainIs: run_benchs.ml - BuildDepends: containers, containers.advanced, + BuildDepends: containers, containers.advanced, QTest2Lib, containers.data, containers.string, containers.iter, containers.thread, sequence, gen, benchmark, hamt diff --git a/benchs/run_benchs.ml b/benchs/run_benchs.ml index a7c5c1d1..3daf52ae 100644 --- a/benchs/run_benchs.ml +++ b/benchs/run_benchs.ml @@ -1081,7 +1081,6 @@ module Thread = struct end module Graph = struct - (* divisors graph *) let div_children_ i = (* divisors of [i] that are [>= j] *) @@ -1155,6 +1154,115 @@ module Graph = struct ) end +module Str = struct + (* random string, but always returns the same for a given size *) + let rand_str_ n = + let module Q = Quickcheck in + let st = Random.State.make [| n |] in + let gen_c = Q.Gen.oneofl (CCString.to_list "abcdefghijkl") in + Q.Gen.string_size ~gen:gen_c (Q.Gen.return n) st + + (* note: inefficient *) + let find ?(start=0) ~sub s = + let n = String.length sub in + let i = ref start in + try + while !i + n <= String.length s do + if CCString.is_sub ~sub 0 s !i ~len:n then raise Exit; + incr i + done; + -1 + with Exit -> + !i + + (* note: inefficient *) + let rfind ~sub s = + let n = String.length sub in + let i = ref (String.length s - n) in + try + while !i >= 0 do + if CCString.is_sub ~sub 0 s !i ~len:n then raise Exit; + decr i + done; + ~-1 + with Exit -> + !i + + let find_all ?(start=0) ~sub s = + let i = ref start in + fun () -> + let res = find ~sub s ~start:!i in + if res = ~-1 then None + else ( + i := res + String.length sub; + Some res + ) + + let find_all_l ?start ~sub s = find_all ?start ~sub s |> Gen.to_list + + let pp_pb needle haystack = + Format.printf "search needle `%s` in `%s`...@." + needle (String.sub haystack 0 (min 300 (String.length haystack))) + + (* benchmark String.{,r}find *) + let bench_find_ ~dir ~size n = + let needle = rand_str_ size in + let haystack = rand_str_ n in + pp_pb needle haystack; + let mk_naive = match dir with + | `Direct -> fun () -> find ~sub:needle haystack + | `Reverse -> fun () -> rfind ~sub:needle haystack + and mk_current = match dir with + | `Direct -> fun () -> CCString.find ~sub:needle haystack + | `Reverse -> fun () -> CCString.rfind ~sub:needle haystack + in + assert (mk_naive () = mk_current ()); + B.throughputN 3 ~repeat + [ "naive", mk_naive, () + ; "current", mk_current, () + ] + + (* benchmark String.find_all *) + let bench_find_all ~size n = + let needle = rand_str_ size in + let haystack = rand_str_ n in + pp_pb needle haystack; + let mk_naive () = find_all_l ~sub:needle haystack + and mk_current () = CCString.find_all_l ~sub:needle haystack in + assert (mk_naive () = mk_current ()); + B.throughputN 3 ~repeat + [ "naive", mk_naive, () + ; "current", mk_current, () + ] + + let bench_find = bench_find_ ~dir:`Direct + let bench_rfind = bench_find_ ~dir:`Reverse + + let () = B.Tree.register ( + "string" @>>> + [ "find" @>>> + [ "1" @>> app_ints (bench_find ~size:1) [100; 100_000; 500_000] + ; "5" @>> app_ints (bench_find ~size:5) [100; 100_000; 500_000] + ; "15" @>> app_ints (bench_find ~size:15) [100; 100_000; 500_000] + ; "50" @>> app_ints (bench_find ~size:50) [100; 100_000; 500_000] + ; "500" @>> app_ints (bench_find ~size:500) [100_000; 500_000] + ]; + "find_all" @>>> + [ "1" @>> app_ints (bench_find_all ~size:1) [100; 100_000; 500_000] + ; "5" @>> app_ints (bench_find_all ~size:5) [100; 100_000; 500_000] + ; "15" @>> app_ints (bench_find_all ~size:15) [100; 100_000; 500_000] + ; "50" @>> app_ints (bench_find_all ~size:50) [100; 100_000; 500_000] + ; "500" @>> app_ints (bench_find_all ~size:500) [100_000; 500_000] + ]; + "rfind" @>>> + [ "15" @>> app_ints (bench_rfind ~size:15) [100; 100_000; 500_000] + ; "50" @>> app_ints (bench_rfind ~size:50) [100; 100_000; 500_000] + ; "500" @>> app_ints (bench_rfind ~size:500) [100_000; 500_000] + ]; + ]) + +end + module Alloc = struct module type ALLOC_ARR = sig type 'a t diff --git a/src/string/CCKMP.ml b/src/string/CCKMP.ml index 1b7073b5..5511fad1 100644 --- a/src/string/CCKMP.ml +++ b/src/string/CCKMP.ml @@ -1,27 +1,5 @@ -(* -copyright (c) 2013-2014, simon cruanes -all rights reserved. -redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. redistributions in binary -form must reproduce the above copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other materials provided with -the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*) +(* This file is free software, part of containers. See file "license" for more details. *) (** {1 Knuth-Morris-Pratt} *) diff --git a/src/string/CCKMP.mli b/src/string/CCKMP.mli index 7d8f8d56..13b059f5 100644 --- a/src/string/CCKMP.mli +++ b/src/string/CCKMP.mli @@ -1,27 +1,5 @@ -(* -copyright (c) 2013-2014, simon cruanes -all rights reserved. -redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. redistributions in binary -form must reproduce the above copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other materials provided with -the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*) +(* This file is free software, part of containers. See file "license" for more details. *) (** {1 Knuth-Morris-Pratt} *)