1fb6c1f39Sopenharmony_ci/* 2fb6c1f39Sopenharmony_ciThis module defines benchmarks for the memmem family of functions. 3fb6c1f39Sopenharmony_ciBenchmarking a substring algorithm is particularly difficult, especially 4fb6c1f39Sopenharmony_ciwhen implementations (like this one, and others) use heuristics to speed up 5fb6c1f39Sopenharmony_cicommon cases, typically at the expense of less common cases. The job of this 6fb6c1f39Sopenharmony_cibenchmark suite is to not only highlight the fast common cases, but to also put 7fb6c1f39Sopenharmony_cia spotlight on the less common or pathological cases. While some things are 8fb6c1f39Sopenharmony_cigenerally expected to be slower because of these heuristics, the benchmarks 9fb6c1f39Sopenharmony_cihelp us make sure they we don't let things get too slow. 10fb6c1f39Sopenharmony_ci 11fb6c1f39Sopenharmony_ciThe naming scheme is as follows: 12fb6c1f39Sopenharmony_ci 13fb6c1f39Sopenharmony_ci memr?mem/{impl}/{config}/{corpus}/{needle} 14fb6c1f39Sopenharmony_ci 15fb6c1f39Sopenharmony_ciWhere {...} is a variable. Variables should never contain slashes. They are as 16fb6c1f39Sopenharmony_cifollows: 17fb6c1f39Sopenharmony_ci 18fb6c1f39Sopenharmony_ci impl 19fb6c1f39Sopenharmony_ci A brief name describing the implementation under test. Possible values: 20fb6c1f39Sopenharmony_ci 21fb6c1f39Sopenharmony_ci krate 22fb6c1f39Sopenharmony_ci The implementation provided by this crate. 23fb6c1f39Sopenharmony_ci krate-nopre 24fb6c1f39Sopenharmony_ci The implementation provided by this crate without prefilters enabled. 25fb6c1f39Sopenharmony_ci bstr 26fb6c1f39Sopenharmony_ci The implementation provided by the bstr crate. 27fb6c1f39Sopenharmony_ci N.B. This is only applicable at time of writing, since bstr will 28fb6c1f39Sopenharmony_ci eventually just use this crate. 29fb6c1f39Sopenharmony_ci regex 30fb6c1f39Sopenharmony_ci The implementation of substring search provided by the regex crate. 31fb6c1f39Sopenharmony_ci N.B. This is only applicable at time of writing, since regex will 32fb6c1f39Sopenharmony_ci eventually just use this crate. 33fb6c1f39Sopenharmony_ci stud 34fb6c1f39Sopenharmony_ci The implementation of substring search provided by the standard 35fb6c1f39Sopenharmony_ci library. This implementation only works on valid UTF-8 by virtue of 36fb6c1f39Sopenharmony_ci how its API is exposed. 37fb6c1f39Sopenharmony_ci twoway 38fb6c1f39Sopenharmony_ci The implementation of substring search provided by the twoway crate. 39fb6c1f39Sopenharmony_ci sliceslice 40fb6c1f39Sopenharmony_ci The implementation of substring search provided by the sliceslice crate. 41fb6c1f39Sopenharmony_ci libc 42fb6c1f39Sopenharmony_ci The implementation of memmem in your friendly neighborhood libc. 43fb6c1f39Sopenharmony_ci 44fb6c1f39Sopenharmony_ci Note that there is also a 'memmem' crate, but it is unmaintained and 45fb6c1f39Sopenharmony_ci appears to just be a snapshot of std's implementation at a particular 46fb6c1f39Sopenharmony_ci point in time (but exposed in a way to permit it to search arbitrary 47fb6c1f39Sopenharmony_ci bytes). 48fb6c1f39Sopenharmony_ci 49fb6c1f39Sopenharmony_ci config 50fb6c1f39Sopenharmony_ci This should be a brief description of the configuration of the search. Not 51fb6c1f39Sopenharmony_ci all implementations can be benchmarked in all configurations. It depends on 52fb6c1f39Sopenharmony_ci the API they expose. Possible values: 53fb6c1f39Sopenharmony_ci 54fb6c1f39Sopenharmony_ci oneshot 55fb6c1f39Sopenharmony_ci Executes a single search without pre-building a searcher. That 56fb6c1f39Sopenharmony_ci this measurement includes the time it takes to initialize a 57fb6c1f39Sopenharmony_ci searcher. 58fb6c1f39Sopenharmony_ci prebuilt 59fb6c1f39Sopenharmony_ci Executes a single search without measuring the time it takes to 60fb6c1f39Sopenharmony_ci build a searcher. 61fb6c1f39Sopenharmony_ci iter-oneshot 62fb6c1f39Sopenharmony_ci Counts the total number of matches. This measures the time it takes to 63fb6c1f39Sopenharmony_ci build the searcher. 64fb6c1f39Sopenharmony_ci iter-prebuilt 65fb6c1f39Sopenharmony_ci Counts the total number of matches. This does not measure the time it 66fb6c1f39Sopenharmony_ci takes to build the searcher. 67fb6c1f39Sopenharmony_ci 68fb6c1f39Sopenharmony_ci corpus 69fb6c1f39Sopenharmony_ci A brief name describing the corpus or haystack used in the benchmark. In 70fb6c1f39Sopenharmony_ci general, we vary this with regard to size and language. Possible values: 71fb6c1f39Sopenharmony_ci 72fb6c1f39Sopenharmony_ci subtitles-{en,ru,zh} 73fb6c1f39Sopenharmony_ci Text from the OpenSubtitles project, in one of English, Russian or 74fb6c1f39Sopenharmony_ci Chinese. This is the primary input meant to represent most kinds of 75fb6c1f39Sopenharmony_ci haystacks. 76fb6c1f39Sopenharmony_ci pathological-{...} 77fb6c1f39Sopenharmony_ci A haystack that has been specifically constructed to exploit a 78fb6c1f39Sopenharmony_ci pathological case in or more substring search implementations. 79fb6c1f39Sopenharmony_ci sliceslice-words 80fb6c1f39Sopenharmony_ci The haystack is varied across words in an English dictionary. Using 81fb6c1f39Sopenharmony_ci this corpus means the benchmark is measuring performance on very small 82fb6c1f39Sopenharmony_ci haystacks. This was taken from the sliceslice crate benchmarks. 83fb6c1f39Sopenharmony_ci sliceslice-i386 84fb6c1f39Sopenharmony_ci The haystack is an Intel 80386 reference manual. 85fb6c1f39Sopenharmony_ci This was also taken from the sliceslice crate benchmarks. 86fb6c1f39Sopenharmony_ci 87fb6c1f39Sopenharmony_ci needle 88fb6c1f39Sopenharmony_ci A brief name describing the needle used. Unlike other variables, there 89fb6c1f39Sopenharmony_ci isn't a strong controlled vocabularly for this parameter. The needle 90fb6c1f39Sopenharmony_ci variable is meant to be largely self explanatory. For example, a needle 91fb6c1f39Sopenharmony_ci named "rare" probably means that the number of occurrences of the needle 92fb6c1f39Sopenharmony_ci is expected to be particularly low. 93fb6c1f39Sopenharmony_ci*/ 94fb6c1f39Sopenharmony_ci 95fb6c1f39Sopenharmony_ciuse criterion::Criterion; 96fb6c1f39Sopenharmony_ci 97fb6c1f39Sopenharmony_ciuse crate::{define, memmem::inputs::INPUTS}; 98fb6c1f39Sopenharmony_ci 99fb6c1f39Sopenharmony_cimod imp; 100fb6c1f39Sopenharmony_cimod inputs; 101fb6c1f39Sopenharmony_cimod sliceslice; 102fb6c1f39Sopenharmony_ci 103fb6c1f39Sopenharmony_cipub fn all(c: &mut Criterion) { 104fb6c1f39Sopenharmony_ci oneshot(c); 105fb6c1f39Sopenharmony_ci prebuilt(c); 106fb6c1f39Sopenharmony_ci oneshot_iter(c); 107fb6c1f39Sopenharmony_ci prebuilt_iter(c); 108fb6c1f39Sopenharmony_ci sliceslice::all(c); 109fb6c1f39Sopenharmony_ci} 110fb6c1f39Sopenharmony_ci 111fb6c1f39Sopenharmony_cifn oneshot(c: &mut Criterion) { 112fb6c1f39Sopenharmony_ci macro_rules! def_impl { 113fb6c1f39Sopenharmony_ci ($inp:expr, $q:expr, $freq:expr, $impl:ident) => { 114fb6c1f39Sopenharmony_ci let config = "oneshot"; 115fb6c1f39Sopenharmony_ci let available = imp::$impl::available($q.needle); 116fb6c1f39Sopenharmony_ci // We only define non-iter benchmarks when the count is <=1. Such 117fb6c1f39Sopenharmony_ci // queries are usually constructed to only appear at the end. 118fb6c1f39Sopenharmony_ci // Otherwise, for more common queries, the benchmark would be 119fb6c1f39Sopenharmony_ci // approximately duplicative with benchmarks on shorter haystacks 120fb6c1f39Sopenharmony_ci // for the implementations we benchmark. 121fb6c1f39Sopenharmony_ci if $q.count <= 1 && available.contains(&config) { 122fb6c1f39Sopenharmony_ci let expected = $q.count > 0; 123fb6c1f39Sopenharmony_ci macro_rules! define { 124fb6c1f39Sopenharmony_ci ($dir:expr, $find:expr) => { 125fb6c1f39Sopenharmony_ci let name = format!( 126fb6c1f39Sopenharmony_ci "{dir}/{imp}/{config}/{inp}/{freq}-{q}", 127fb6c1f39Sopenharmony_ci dir = $dir, 128fb6c1f39Sopenharmony_ci imp = stringify!($impl), 129fb6c1f39Sopenharmony_ci config = config, 130fb6c1f39Sopenharmony_ci inp = $inp.name, 131fb6c1f39Sopenharmony_ci freq = $freq, 132fb6c1f39Sopenharmony_ci q = $q.name, 133fb6c1f39Sopenharmony_ci ); 134fb6c1f39Sopenharmony_ci define( 135fb6c1f39Sopenharmony_ci c, 136fb6c1f39Sopenharmony_ci &name, 137fb6c1f39Sopenharmony_ci $inp.corpus.as_bytes(), 138fb6c1f39Sopenharmony_ci Box::new(move |b| { 139fb6c1f39Sopenharmony_ci b.iter(|| { 140fb6c1f39Sopenharmony_ci assert_eq!( 141fb6c1f39Sopenharmony_ci expected, 142fb6c1f39Sopenharmony_ci $find($inp.corpus, $q.needle) 143fb6c1f39Sopenharmony_ci ); 144fb6c1f39Sopenharmony_ci }); 145fb6c1f39Sopenharmony_ci }), 146fb6c1f39Sopenharmony_ci ); 147fb6c1f39Sopenharmony_ci }; 148fb6c1f39Sopenharmony_ci } 149fb6c1f39Sopenharmony_ci define!("memmem", imp::$impl::fwd::oneshot); 150fb6c1f39Sopenharmony_ci if available.contains(&"reverse") { 151fb6c1f39Sopenharmony_ci define!("memrmem", imp::$impl::rev::oneshot); 152fb6c1f39Sopenharmony_ci } 153fb6c1f39Sopenharmony_ci } 154fb6c1f39Sopenharmony_ci }; 155fb6c1f39Sopenharmony_ci } 156fb6c1f39Sopenharmony_ci macro_rules! def_all_impls { 157fb6c1f39Sopenharmony_ci ($inp:expr, $q:expr, $freq:expr) => { 158fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, krate); 159fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, krate_nopre); 160fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, bstr); 161fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, regex); 162fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, stud); 163fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, twoway); 164fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, sliceslice); 165fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, libc); 166fb6c1f39Sopenharmony_ci }; 167fb6c1f39Sopenharmony_ci } 168fb6c1f39Sopenharmony_ci for inp in INPUTS { 169fb6c1f39Sopenharmony_ci for q in inp.never { 170fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "never"); 171fb6c1f39Sopenharmony_ci } 172fb6c1f39Sopenharmony_ci for q in inp.rare { 173fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "rare"); 174fb6c1f39Sopenharmony_ci } 175fb6c1f39Sopenharmony_ci for q in inp.common { 176fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "common"); 177fb6c1f39Sopenharmony_ci } 178fb6c1f39Sopenharmony_ci } 179fb6c1f39Sopenharmony_ci} 180fb6c1f39Sopenharmony_ci 181fb6c1f39Sopenharmony_cifn prebuilt(c: &mut Criterion) { 182fb6c1f39Sopenharmony_ci macro_rules! def_impl { 183fb6c1f39Sopenharmony_ci ($inp:expr, $q:expr, $freq:expr, $impl:ident) => { 184fb6c1f39Sopenharmony_ci let config = "prebuilt"; 185fb6c1f39Sopenharmony_ci let available = imp::$impl::available($q.needle); 186fb6c1f39Sopenharmony_ci // We only define non-iter benchmarks when the count is <=1. Such 187fb6c1f39Sopenharmony_ci // queries are usually constructed to only appear at the end. 188fb6c1f39Sopenharmony_ci // Otherwise, for more common queries, the benchmark would be 189fb6c1f39Sopenharmony_ci // approximately duplicative with benchmarks on shorter haystacks 190fb6c1f39Sopenharmony_ci // for the implementations we benchmark. 191fb6c1f39Sopenharmony_ci if $q.count <= 1 && available.contains(&config) { 192fb6c1f39Sopenharmony_ci let expected = $q.count > 0; 193fb6c1f39Sopenharmony_ci macro_rules! define { 194fb6c1f39Sopenharmony_ci ($dir:expr, $new_finder:expr) => { 195fb6c1f39Sopenharmony_ci let name = format!( 196fb6c1f39Sopenharmony_ci "{dir}/{imp}/{config}/{inp}/{freq}-{q}", 197fb6c1f39Sopenharmony_ci dir = $dir, 198fb6c1f39Sopenharmony_ci imp = stringify!($impl), 199fb6c1f39Sopenharmony_ci config = config, 200fb6c1f39Sopenharmony_ci inp = $inp.name, 201fb6c1f39Sopenharmony_ci freq = $freq, 202fb6c1f39Sopenharmony_ci q = $q.name, 203fb6c1f39Sopenharmony_ci ); 204fb6c1f39Sopenharmony_ci define( 205fb6c1f39Sopenharmony_ci c, 206fb6c1f39Sopenharmony_ci &name, 207fb6c1f39Sopenharmony_ci $inp.corpus.as_bytes(), 208fb6c1f39Sopenharmony_ci Box::new(move |b| { 209fb6c1f39Sopenharmony_ci let find = $new_finder($q.needle); 210fb6c1f39Sopenharmony_ci b.iter(|| { 211fb6c1f39Sopenharmony_ci assert_eq!(expected, find($inp.corpus)); 212fb6c1f39Sopenharmony_ci }); 213fb6c1f39Sopenharmony_ci }), 214fb6c1f39Sopenharmony_ci ); 215fb6c1f39Sopenharmony_ci }; 216fb6c1f39Sopenharmony_ci } 217fb6c1f39Sopenharmony_ci define!("memmem", imp::$impl::fwd::prebuilt); 218fb6c1f39Sopenharmony_ci if available.contains(&"reverse") { 219fb6c1f39Sopenharmony_ci define!("memrmem", imp::$impl::rev::prebuilt); 220fb6c1f39Sopenharmony_ci } 221fb6c1f39Sopenharmony_ci } 222fb6c1f39Sopenharmony_ci }; 223fb6c1f39Sopenharmony_ci } 224fb6c1f39Sopenharmony_ci macro_rules! def_all_impls { 225fb6c1f39Sopenharmony_ci ($inp:expr, $q:expr, $freq:expr) => { 226fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, krate); 227fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, krate_nopre); 228fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, bstr); 229fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, regex); 230fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, stud); 231fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, twoway); 232fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, sliceslice); 233fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, libc); 234fb6c1f39Sopenharmony_ci }; 235fb6c1f39Sopenharmony_ci } 236fb6c1f39Sopenharmony_ci for inp in INPUTS { 237fb6c1f39Sopenharmony_ci for q in inp.never { 238fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "never"); 239fb6c1f39Sopenharmony_ci } 240fb6c1f39Sopenharmony_ci for q in inp.rare { 241fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "rare"); 242fb6c1f39Sopenharmony_ci } 243fb6c1f39Sopenharmony_ci for q in inp.common { 244fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "common"); 245fb6c1f39Sopenharmony_ci } 246fb6c1f39Sopenharmony_ci } 247fb6c1f39Sopenharmony_ci} 248fb6c1f39Sopenharmony_ci 249fb6c1f39Sopenharmony_cifn oneshot_iter(c: &mut Criterion) { 250fb6c1f39Sopenharmony_ci macro_rules! def_impl { 251fb6c1f39Sopenharmony_ci ($inp:expr, $q:expr, $freq:expr, $impl:ident) => { 252fb6c1f39Sopenharmony_ci let config = "oneshotiter"; 253fb6c1f39Sopenharmony_ci let available = imp::$impl::available($q.needle); 254fb6c1f39Sopenharmony_ci // We only define iter benchmarks when the count is >1. Since 255fb6c1f39Sopenharmony_ci // queries with count<=1 are usually constructed such that the 256fb6c1f39Sopenharmony_ci // match appears at the end of the haystack, it doesn't make much 257fb6c1f39Sopenharmony_ci // sense to also benchmark iteration for that case. Instead, we only 258fb6c1f39Sopenharmony_ci // benchmark iteration for queries that match more frequently. 259fb6c1f39Sopenharmony_ci if $q.count > 1 && available.contains(&config) { 260fb6c1f39Sopenharmony_ci macro_rules! define { 261fb6c1f39Sopenharmony_ci ($dir:expr, $find_iter:expr) => { 262fb6c1f39Sopenharmony_ci let name = format!( 263fb6c1f39Sopenharmony_ci "{dir}/{imp}/{config}/{inp}/{freq}-{q}", 264fb6c1f39Sopenharmony_ci dir = $dir, 265fb6c1f39Sopenharmony_ci imp = stringify!($impl), 266fb6c1f39Sopenharmony_ci config = config, 267fb6c1f39Sopenharmony_ci inp = $inp.name, 268fb6c1f39Sopenharmony_ci freq = $freq, 269fb6c1f39Sopenharmony_ci q = $q.name, 270fb6c1f39Sopenharmony_ci ); 271fb6c1f39Sopenharmony_ci define( 272fb6c1f39Sopenharmony_ci c, 273fb6c1f39Sopenharmony_ci &name, 274fb6c1f39Sopenharmony_ci $inp.corpus.as_bytes(), 275fb6c1f39Sopenharmony_ci Box::new(move |b| { 276fb6c1f39Sopenharmony_ci b.iter(|| { 277fb6c1f39Sopenharmony_ci let it = 278fb6c1f39Sopenharmony_ci $find_iter($inp.corpus, $q.needle); 279fb6c1f39Sopenharmony_ci assert_eq!($q.count, it.count()); 280fb6c1f39Sopenharmony_ci }); 281fb6c1f39Sopenharmony_ci }), 282fb6c1f39Sopenharmony_ci ); 283fb6c1f39Sopenharmony_ci }; 284fb6c1f39Sopenharmony_ci } 285fb6c1f39Sopenharmony_ci define!("memmem", imp::$impl::fwd::oneshotiter); 286fb6c1f39Sopenharmony_ci if available.contains(&"reverse") { 287fb6c1f39Sopenharmony_ci define!("memrmem", imp::$impl::rev::oneshotiter); 288fb6c1f39Sopenharmony_ci } 289fb6c1f39Sopenharmony_ci } 290fb6c1f39Sopenharmony_ci }; 291fb6c1f39Sopenharmony_ci } 292fb6c1f39Sopenharmony_ci macro_rules! def_all_impls { 293fb6c1f39Sopenharmony_ci ($inp:expr, $q:expr, $freq:expr) => { 294fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, krate); 295fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, krate_nopre); 296fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, bstr); 297fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, regex); 298fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, stud); 299fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, twoway); 300fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, sliceslice); 301fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, libc); 302fb6c1f39Sopenharmony_ci }; 303fb6c1f39Sopenharmony_ci } 304fb6c1f39Sopenharmony_ci for inp in INPUTS { 305fb6c1f39Sopenharmony_ci for q in inp.never { 306fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "never"); 307fb6c1f39Sopenharmony_ci } 308fb6c1f39Sopenharmony_ci for q in inp.rare { 309fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "rare"); 310fb6c1f39Sopenharmony_ci } 311fb6c1f39Sopenharmony_ci for q in inp.common { 312fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "common"); 313fb6c1f39Sopenharmony_ci } 314fb6c1f39Sopenharmony_ci } 315fb6c1f39Sopenharmony_ci} 316fb6c1f39Sopenharmony_ci 317fb6c1f39Sopenharmony_cifn prebuilt_iter(c: &mut Criterion) { 318fb6c1f39Sopenharmony_ci macro_rules! def_impl { 319fb6c1f39Sopenharmony_ci ($inp:expr, $q:expr, $freq:expr, $impl:ident) => { 320fb6c1f39Sopenharmony_ci let config = "prebuiltiter"; 321fb6c1f39Sopenharmony_ci let available = imp::$impl::available($q.needle); 322fb6c1f39Sopenharmony_ci // We only define iter benchmarks when the count is >1. Since 323fb6c1f39Sopenharmony_ci // queries with count<=1 are usually constructed such that the 324fb6c1f39Sopenharmony_ci // match appears at the end of the haystack, it doesn't make much 325fb6c1f39Sopenharmony_ci // sense to also benchmark iteration for that case. Instead, we only 326fb6c1f39Sopenharmony_ci // benchmark iteration for queries that match more frequently. 327fb6c1f39Sopenharmony_ci if $q.count > 1 && available.contains(&config) { 328fb6c1f39Sopenharmony_ci macro_rules! define { 329fb6c1f39Sopenharmony_ci ($dir:expr, $new_finder:expr) => { 330fb6c1f39Sopenharmony_ci let name = format!( 331fb6c1f39Sopenharmony_ci "{dir}/{imp}/{config}/{inp}/{freq}-{q}", 332fb6c1f39Sopenharmony_ci dir = $dir, 333fb6c1f39Sopenharmony_ci imp = stringify!($impl), 334fb6c1f39Sopenharmony_ci config = config, 335fb6c1f39Sopenharmony_ci inp = $inp.name, 336fb6c1f39Sopenharmony_ci freq = $freq, 337fb6c1f39Sopenharmony_ci q = $q.name, 338fb6c1f39Sopenharmony_ci ); 339fb6c1f39Sopenharmony_ci define( 340fb6c1f39Sopenharmony_ci c, 341fb6c1f39Sopenharmony_ci &name, 342fb6c1f39Sopenharmony_ci $inp.corpus.as_bytes(), 343fb6c1f39Sopenharmony_ci Box::new(move |b| { 344fb6c1f39Sopenharmony_ci let finder = $new_finder($q.needle); 345fb6c1f39Sopenharmony_ci b.iter(|| { 346fb6c1f39Sopenharmony_ci let it = finder.iter($inp.corpus); 347fb6c1f39Sopenharmony_ci assert_eq!($q.count, it.count()); 348fb6c1f39Sopenharmony_ci }); 349fb6c1f39Sopenharmony_ci }), 350fb6c1f39Sopenharmony_ci ); 351fb6c1f39Sopenharmony_ci }; 352fb6c1f39Sopenharmony_ci } 353fb6c1f39Sopenharmony_ci define!("memmem", imp::$impl::fwd::prebuiltiter); 354fb6c1f39Sopenharmony_ci if available.contains(&"reverse") { 355fb6c1f39Sopenharmony_ci define!("memrmem", imp::$impl::rev::prebuiltiter); 356fb6c1f39Sopenharmony_ci } 357fb6c1f39Sopenharmony_ci } 358fb6c1f39Sopenharmony_ci }; 359fb6c1f39Sopenharmony_ci } 360fb6c1f39Sopenharmony_ci macro_rules! def_all_impls { 361fb6c1f39Sopenharmony_ci ($inp:expr, $q:expr, $freq:expr) => { 362fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, krate); 363fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, krate_nopre); 364fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, bstr); 365fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, regex); 366fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, stud); 367fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, twoway); 368fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, sliceslice); 369fb6c1f39Sopenharmony_ci def_impl!($inp, $q, $freq, libc); 370fb6c1f39Sopenharmony_ci }; 371fb6c1f39Sopenharmony_ci } 372fb6c1f39Sopenharmony_ci for inp in INPUTS { 373fb6c1f39Sopenharmony_ci for q in inp.never { 374fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "never"); 375fb6c1f39Sopenharmony_ci } 376fb6c1f39Sopenharmony_ci for q in inp.rare { 377fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "rare"); 378fb6c1f39Sopenharmony_ci } 379fb6c1f39Sopenharmony_ci for q in inp.common { 380fb6c1f39Sopenharmony_ci def_all_impls!(inp, q, "common"); 381fb6c1f39Sopenharmony_ci } 382fb6c1f39Sopenharmony_ci } 383fb6c1f39Sopenharmony_ci} 384