@@ -1177,6 +1177,99 @@ module Str = struct
11771177  let  bench_find  =  bench_find_ ~dir: `Direct 
11781178  let  bench_rfind  =  bench_find_ ~dir: `Reverse 
11791179
1180+   module  Pre  =  struct 
1181+     let  prefix_rec  ~pre   s  = 
1182+       let  rec  same  s1  s2  i  = 
1183+         if  i =  String. length s1 then  true 
1184+         else  (
1185+           String. unsafe_get s1 i =  String. unsafe_get s2 i &&  same s1 s2 (i+ 1 )
1186+         )
1187+       in 
1188+       String. length pre < =  String. length s && 
1189+       same pre s 0 
1190+ 
1191+     let  prefix_while  ~pre   s  = 
1192+       String. length pre < =  String. length s && 
1193+       begin 
1194+         let  i =  ref  0  in 
1195+         while  ! i <  String. length pre && 
1196+               String. unsafe_get s ! i =  String. unsafe_get pre ! i
1197+         do  incr i done ;
1198+         ! i =  String. length pre
1199+       end 
1200+ 
1201+     exception  Exit_false 
1202+ 
1203+     let  prefix_for_exn  ~pre   s  = 
1204+       String. length pre < =  String. length s && 
1205+       try 
1206+         for  i= 0  to  String. length pre-1  do 
1207+           if  String. unsafe_get s i !=  String. unsafe_get pre i
1208+           then  raise Exit_false 
1209+         done ;
1210+         true 
1211+       with  Exit_false  ->  false 
1212+ 
1213+     let  prefix_sub  ~pre :prfx   s  = 
1214+       let  len_s =  String. length s in 
1215+       let  len_p =  String. length prfx in 
1216+       if  len_s <  len_p then 
1217+         false 
1218+       else 
1219+         let  sub =  String. sub s 0  len_p in 
1220+         CCString. equal prfx sub
1221+ 
1222+     let  bat_prefix  ~pre :p   str  = 
1223+       let  len =  String. length p in 
1224+       if  String. length str <  len then  false 
1225+       else 
1226+         let  rec  loop  str  p  i  = 
1227+           if  i =  len then  true 
1228+           else  if  String. unsafe_get str i <>  String. unsafe_get p i then  false 
1229+           else  loop str p (i +  1 )
1230+         in  loop str p 0 
1231+ 
1232+     let  make  ~max_len   ~max_len_prefix   n  = 
1233+       let  rand =  Random.State. make_self_init ()  in 
1234+       let  input = 
1235+         Array. init n
1236+           (fun  _  ->
1237+              let  str = 
1238+                QCheck.Gen. (string_size ~gen: printable (10  --  max_len))
1239+                |>  QCheck.Gen. generate1 ~rand 
1240+              in 
1241+              let  prfx_len =  Random.State. int  rand (min max_len_prefix (String. length str +  1 )) in 
1242+              let  prfx = 
1243+                if  Random.State. bool  rand then 
1244+                  String. sub str 0  prfx_len
1245+                else 
1246+                  String. sub str (String. length str -  prfx_len) prfx_len
1247+              in 
1248+              (prfx, str))
1249+       in 
1250+       let  output = 
1251+         Array. map
1252+           (fun  (pre , str ) -> prefix_rec ~pre  str)
1253+           input
1254+       in 
1255+       let  test  f  ()  = 
1256+         Array. iteri
1257+           (fun  i  (pre , y ) ->
1258+              let  res =  f ~pre  y in 
1259+              assert  (res =  output.(i)))
1260+           input
1261+       in 
1262+       Benchmark. throughputN 3 
1263+         [
1264+           " containers" CCString. prefix, () ;
1265+           " while_unsafe" () ;
1266+           " rec_unsafe" () ;
1267+           " for_exn_unsafe" () ;
1268+           " sub_eq" () ;
1269+           " bat_prefix" () ;
1270+         ]
1271+   end 
1272+ 
11801273  let  ()  =  B.Tree. register (
11811274    " string" @>>> 
11821275      [ " find" @>>> 
@@ -1205,6 +1298,11 @@ module Str = struct
12051298          ; " 50" @>>  app_ints (bench_rfind ~size: 50 ) [100 ; 100_000 ; 500_000 ]
12061299          ; " 500" @>>  app_ints (bench_rfind ~size: 500 ) [100_000 ; 500_000 ]
12071300          ];
1301+         " prefix" @>>> 
1302+         [ " max_len:1000,max_pre_len:15" @>>  app_ints (Pre. make ~max_len: 1000  ~max_len_prefix: 15 ) [100 ; 1_000 ];
1303+           " max_len:1000,max_pre_len:100" @>>  app_ints (Pre. make ~max_len: 1000  ~max_len_prefix: 100 ) [100 ; 1_000 ];
1304+           " max_len:1000,max_pre_len:300" @>>  app_ints (Pre. make ~max_len: 1000  ~max_len_prefix: 300 ) [100 ; 1_000 ];
1305+         ]
12081306      ])
12091307
12101308end
0 commit comments