#[cfg(feature = "bench")] use scaling::{bench, bench_gen_env}; #[cfg(feature = "bench")] use std::collections::HashSet; #[cfg(feature = "bench")] use internment::{ArcIntern, Arena, Intern, NewIntern}; #[cfg(not(feature = "bench"))] fn main() { println!("Enable bench feature if you want a benchmark") } #[cfg(feature = "bench")] macro_rules! four_types { ($intern:ident, $i:expr) => { $intern::::benchmarking_only_clear_interns(); $intern::::benchmarking_only_clear_interns(); $intern::<(usize, usize)>::benchmarking_only_clear_interns(); $intern::<(usize, usize, usize)>::benchmarking_only_clear_interns(); let mut interned_strings = Vec::new(); let mut interned_ints = Vec::new(); let mut interned_pairs = Vec::new(); let mut interned_triples = Vec::new(); for n in 0..100000 { match ($i + n) % 4 { 0 => { interned_strings.push($intern::new(format!("i {} and n {}", $i, n))); } 1 => { interned_ints.push($intern::new($i * n * 137)); } 2 => { interned_pairs.push($intern::new(($i, n))); } _ => { interned_triples.push($intern::new(($i, n, $i + n))); } } } }; } #[cfg(feature = "bench")] macro_rules! same_arrays { ($intern:ident, $i:expr) => { $intern::<[usize; 1000]>::benchmarking_only_clear_interns(); $intern::<[usize; 20]>::benchmarking_only_clear_interns(); $intern::<[usize; 30]>::benchmarking_only_clear_interns(); $intern::<[usize; 40]>::benchmarking_only_clear_interns(); $intern::<[usize; 50]>::benchmarking_only_clear_interns(); $intern::<[usize; 60]>::benchmarking_only_clear_interns(); $intern::<[usize; 70]>::benchmarking_only_clear_interns(); $intern::<[usize; 80]>::benchmarking_only_clear_interns(); $intern::<[usize; 90]>::benchmarking_only_clear_interns(); $intern::<[usize; 100]>::benchmarking_only_clear_interns(); let mut size = $i; for _ in 0..100000 { size = (size * 75 + 74) % ((1 << 16) + 1); match size % 10 { 0 => { $intern::new([0; 1000]); } 1 => { $intern::new([0; 20]); } 2 => { $intern::new([0; 30]); } 3 => { $intern::new([0; 40]); } 4 => { $intern::new([0; 50]); } 5 => { $intern::new([0; 60]); } 6 => { $intern::new([0; 70]); } 7 => { $intern::new([0; 80]); } 8 => { $intern::new([0; 90]); } _ => { $intern::new([0; 100]); } } } }; } #[cfg(feature = "bench")] macro_rules! different_arrays { ($intern:ident, $i:expr) => { $intern::<[usize; 1000]>::benchmarking_only_clear_interns(); $intern::<[usize; 20]>::benchmarking_only_clear_interns(); $intern::<[usize; 30]>::benchmarking_only_clear_interns(); $intern::<[usize; 40]>::benchmarking_only_clear_interns(); $intern::<[usize; 50]>::benchmarking_only_clear_interns(); $intern::<[usize; 60]>::benchmarking_only_clear_interns(); $intern::<[usize; 70]>::benchmarking_only_clear_interns(); $intern::<[usize; 80]>::benchmarking_only_clear_interns(); $intern::<[usize; 90]>::benchmarking_only_clear_interns(); $intern::<[usize; 100]>::benchmarking_only_clear_interns(); let mut size = $i; for _ in 0..100000 { size = (size * 75 + 74) % ((1 << 16) + 1); match size % 10 { 0 => { $intern::new([size + $i; 1000]); } 1 => { $intern::new([size + $i; 20]); } 2 => { $intern::new([size + $i; 30]); } 3 => { $intern::new([size + $i; 40]); } 4 => { $intern::new([size + $i; 50]); } 5 => { $intern::new([size + $i; 60]); } 6 => { $intern::new([size + $i; 70]); } 7 => { $intern::new([size + $i; 80]); } 8 => { $intern::new([size + $i; 90]); } _ => { $intern::new([size + $i; 100]); } } } }; } #[cfg(feature = "bench")] macro_rules! strings { ($intern:ident, $i:expr) => { $intern::::benchmarking_only_clear_interns(); let mut interned_strings = Vec::new(); for n in 0..100000 { interned_strings.push($intern::new(format!("i {} and n {}", $i, n))); } }; } #[cfg(feature = "bench")] macro_rules! arena_strings { ($intern:ident, $i:expr) => { let arena: Arena = Arena::new(); let mut interned_strings = Vec::new(); for n in 0..100000 { interned_strings.push(arena.intern(format!("i {} and n {}", $i, n))); } }; } #[cfg(feature = "bench")] macro_rules! few_strings { ($intern:ident, $i:expr) => { $intern::::benchmarking_only_clear_interns(); let mut interned_strings = Vec::new(); for n in 0..100000 { interned_strings.push($intern::new( memorable_wordlist::WORDS[($i + n) % 10].to_string(), )); } }; } #[cfg(feature = "bench")] macro_rules! few_str_from { ($intern:ident, $i:expr) => { $intern::::benchmarking_only_clear_interns(); let mut interned_strings: Vec<$intern> = Vec::new(); for n in 0..100000 { let i: $intern = From::from(memorable_wordlist::WORDS[($i + n) % 10]); interned_strings.push(i); } }; } #[cfg(feature = "bench")] macro_rules! few_strings_from { ($intern:ident, $i:expr) => { $intern::::benchmarking_only_clear_interns(); let mut interned_strings: Vec<$intern> = Vec::new(); for n in 0..100000 { interned_strings.push($intern::from_ref(memorable_wordlist::WORDS[($i + n) % 10])); } }; } #[cfg(feature = "bench")] macro_rules! arena_few_strings { ($intern:ident, $i:expr) => { let arena: Arena = Arena::new(); let mut interned_strings: Vec> = Vec::new(); for n in 0..100000 { interned_strings .push(arena.intern(memorable_wordlist::WORDS[($i + n) % 10].to_string())); } }; } #[cfg(feature = "bench")] macro_rules! static_str { ($intern:ident, $i:expr) => { $intern::<&'static str>::benchmarking_only_clear_interns(); let mut interned = Vec::new(); for n in 0..100000 { interned.push($intern::new( memorable_wordlist::WORDS[($i + n) % memorable_wordlist::WORDS.len()], )); } }; } #[cfg(feature = "bench")] macro_rules! arena_static_str { ($intern:ident, $i:expr) => { let arena: Arena<&'static str> = Arena::new(); let mut interned = Vec::new(); for n in 0..100000 { interned.push( arena.intern(memorable_wordlist::WORDS[($i + n) % memorable_wordlist::WORDS.len()]), ); } }; } #[cfg(feature = "bench")] macro_rules! contended { ($intern:ident,$mac:ident) => { bench(|| { let mut handles: Vec> = Vec::new(); for i in 0..50 { handles.push(std::thread::spawn(move || { $mac!($intern, i); })); } for h in handles { h.join().unwrap(); } }) }; } #[cfg(feature = "bench")] macro_rules! uncontended { ($intern:ident,$mac:ident) => { bench(|| { for i in 0..50 { $mac!($intern, i); } }) }; } #[cfg(feature = "bench")] fn main() { println!( " Contended &'static str Intern {}", contended!(Intern, static_str) ); println!( "Uncontended &'static str Intern {}", uncontended!(Intern, static_str) ); println!( " Contended &'stati.. NewIntern {}", contended!(NewIntern, static_str) ); println!( "Uncontended &'stati.. NewIntern {}", uncontended!(NewIntern, static_str) ); println!( " Contended &'stat... ArcIntern {}", contended!(ArcIntern, static_str) ); println!( "Uncontended &'stat... ArcIntern {}", uncontended!(ArcIntern, static_str) ); println!( "Uncontended &'st... ArenaIntern {}", uncontended!(ArenaIntern, arena_static_str) ); println!("\n"); println!( " Contended few Strings Intern {}", contended!(Intern, few_strings) ); println!( "Uncontended few Strings Intern {}", uncontended!(Intern, few_strings) ); println!( " Contended few S... NewIntern {}", contended!(NewIntern, few_strings) ); println!( "Uncontended few S... NewIntern {}", uncontended!(NewIntern, few_strings) ); println!( " Contended few S... ArcIntern {}", contended!(ArcIntern, few_strings) ); println!( "Uncontended few S... ArcIntern {}", uncontended!(ArcIntern, few_strings) ); println!( "Uncontended few S..ArenaIntern {}", uncontended!(ArcIntern, arena_few_strings) ); println!( " Contended few Strings Intern::from {}", contended!(Intern, few_strings_from) ); println!( "Uncontended few Strings Intern::from {}", uncontended!(Intern, few_strings_from) ); println!( " Contended few S... ArcIntern::from {}", contended!(ArcIntern, few_strings_from) ); println!( "Uncontended few S... ArcIntern::from {}", uncontended!(ArcIntern, few_strings_from) ); println!( " Contended few str. Intern::from {}", contended!(Intern, few_str_from) ); println!( "Uncontended few str. Intern::from {}", uncontended!(Intern, few_str_from) ); println!( " Contended few str. NewIntern::from {}", contended!(NewIntern, few_str_from) ); println!( "Uncontended few str. NewIntern::from {}", uncontended!(NewIntern, few_str_from) ); println!("\n"); println!( " Contended unique Strings Intern {}", contended!(Intern, strings) ); println!( "Uncontended unique Strings Intern {}", uncontended!(Intern, strings) ); println!( " Contended unique S... NewIntern {}", contended!(NewIntern, strings) ); println!( "Uncontended unique S... NewIntern {}", uncontended!(NewIntern, strings) ); println!( " Contended unique S... ArcIntern {}", contended!(ArcIntern, strings) ); println!( "Uncontended unique S... ArcIntern {}", uncontended!(ArcIntern, strings) ); println!( "Uncontended unique S..ArenaIntern {}", uncontended!(ArcIntern, arena_strings) ); println!("\n"); println!( " Contended four types Intern {}", contended!(Intern, four_types) ); println!( "Uncontended four types Intern {}", uncontended!(Intern, four_types) ); println!( " Contended four ...NewIntern {}", contended!(NewIntern, four_types) ); println!( "Uncontended four ...NewIntern {}", uncontended!(NewIntern, four_types) ); println!( " Contended four ...ArcIntern {}", contended!(ArcIntern, four_types) ); println!( "Uncontended four ...ArcIntern {}", uncontended!(ArcIntern, four_types) ); println!("\n"); println!( "Contended arrays Intern {}", contended!(Intern, same_arrays) ); println!( "Uncontended ... Intern {}", uncontended!(Intern, same_arrays) ); println!( "Contended ... NewIntern {}", contended!(NewIntern, same_arrays) ); println!( "Uncontended . NewIntern {}", uncontended!(NewIntern, same_arrays) ); println!( "Contended ... ArcIntern {}", contended!(ArcIntern, same_arrays) ); println!( "Uncontended . ArcIntern {}", uncontended!(ArcIntern, same_arrays) ); println!("\n"); println!( "Contended different arrays Intern {}", contended!(Intern, different_arrays) ); println!( "Contended different arrays Intern {}", uncontended!(Intern, different_arrays) ); println!( "Contended different ... NewIntern {}", contended!(NewIntern, different_arrays) ); println!( "Contended different ... NewIntern {}", uncontended!(NewIntern, different_arrays) ); println!( "Contended different ... ArcIntern {}", contended!(ArcIntern, different_arrays) ); println!( "Contended different ... ArcIntern {}", uncontended!(ArcIntern, different_arrays) ); println!("\n"); Intern::new(0i64); ArcIntern::new(0i64); arc_interner::ArcIntern::new(0i64); let s1: HashSet<_> = (1..3000) .map(|i| format!("hello this is a pretty long string {:500}", i)) .collect(); let s_short: HashSet<_> = (1..3000).map(|i| format!("{}", i)).collect(); let s2: HashSet<_> = (1..1000) .map(|i| format!("hello this is a pretty long string also {:500}", i)) .collect(); for x in 0u8..=255 { Intern::new(x); ArcIntern::new(x); arc_interner::ArcIntern::new(x); } { fn mkset(s: &mut HashSet) -> HashSet { let mut n = HashSet::new(); for x in s.iter() { n.insert(x.clone()); } n } mkset(&mut s1.clone()); println!( "String::new short {}", bench_gen_env(|| s_short.clone(), mkset) ); println!("String::new {}", bench_gen_env(|| s1.clone(), mkset)); fn rmset(s: &mut (HashSet, HashSet)) { for x in s.1.iter() { s.0.remove(x); } } let s1: HashSet<_> = s1.clone(); let s2: HashSet<_> = s2.clone(); println!( "String::compare/hash {}", bench_gen_env(|| (s1.clone(), s2.clone()), rmset) ); println!( "String sort {}", bench_gen_env(|| s1.iter().cloned().collect::>(), |v| v.sort()) ); println!( "Box sort {}", bench_gen_env( || s1.iter().map(|s| Box::new(s.clone())).collect::>(), |v| v.sort() ) ); println!( "String any eq {}", bench_gen_env( || s1.iter().cloned().collect::>(), |v| v.iter().any(|s| s == "hello this is a pretty long string") ) ); println!( "Box any eq {}", bench_gen_env( || s1.iter().map(|s| Box::new(s.clone())).collect::>(), |v| v .iter() .any(|s| s.as_str() == "hello this is a pretty long string") ) ); } println!(); println!( "Intern::new {}", bench_gen_env(rand::random::, |x| Intern::new(*x)) ); println!( "Intern::new {}", bench_gen_env(rand::random::, |x| Intern::new(*x)) ); { fn mkset(s: &mut HashSet) -> HashSet> { let mut n = HashSet::new(); for x in s.iter() { n.insert(Intern::new(x.clone())); } n } mkset(&mut s1.clone()); fn mksetfrom(s: &mut HashSet) -> HashSet> { let mut n = HashSet::new(); for x in s.iter() { n.insert(Intern::from_ref(x as &str)); } n } println!( "Intern::new short {}", bench_gen_env(|| s_short.clone(), mkset) ); println!( "Intern::new short {}", bench_gen_env(|| s_short.clone(), mkset) ); println!( "Intern::from short {}", bench_gen_env(|| s_short.clone(), mkset) ); println!( "Intern::new {}", bench_gen_env(|| s1.clone(), mkset) ); println!( "Intern::from {}", bench_gen_env(|| s1.clone(), mksetfrom) ); fn rmset(s: &mut (HashSet>, HashSet>)) { for x in s.1.iter() { s.0.remove(x); } } fn rmset_str(s: &mut (HashSet>, HashSet>)) { for x in s.1.iter() { s.0.remove(x); } } let s1: HashSet<_> = s1.iter().cloned().map(Intern::new).collect(); let s2: HashSet<_> = s2.iter().cloned().map(Intern::new).collect(); let s1_str: HashSet> = s1.iter().cloned().map(|s| From::from(s.as_str())).collect(); let s2_str: HashSet> = s2.iter().cloned().map(|s| From::from(s.as_str())).collect(); println!( "Intern::compare/hash {}", bench_gen_env(|| (s1.clone(), s2.clone()), rmset) ); println!( "Intern::compare/hash {}", bench_gen_env(|| (s1_str.clone(), s2_str.clone()), rmset_str) ); println!( "Intern sort {}", bench_gen_env(|| s1.iter().cloned().collect::>(), |v| v.sort()) ); println!( "Intern sort {}", bench_gen_env( || s1 .iter() .map(|i| From::from(i.as_str())) .collect::>>(), |v| v.sort() ) ); println!( "Intern any eq str {}", bench_gen_env( || s1.iter().cloned().collect::>(), |v| v .iter() .any(|s| s.as_str() == "hello this is a pretty long string") ) ); let value = Intern::new("hello this is a pretty long string".to_string()); println!( "Intern any eq {}", bench_gen_env( || s1.iter().cloned().collect::>(), |v| v.iter().any(|s| *s == value) ) ); } let i = Intern::new(7i64); #[allow(clippy::clone_on_copy)] { println!("Intern::clone {}", bench(|| i.clone())) }; println!(); println!( "ArcIntern::new {}", bench_gen_env(rand::random::, |x| ArcIntern::new(*x)) ); println!( "ArcIntern::new {}", bench_gen_env(rand::random::, |x| ArcIntern::new(*x)) ); { fn mkset(s: &mut HashSet) -> HashSet> { let mut n = HashSet::new(); for x in s.iter() { n.insert(ArcIntern::new(x.clone())); } n } mkset(&mut s1.clone()); println!( "ArcIntern::new short {}", bench_gen_env(|| s_short.clone(), mkset) ); println!( "ArcIntern::new {}", bench_gen_env(|| s1.clone(), mkset) ); fn mksetfrom(s: &mut HashSet) -> HashSet> { let mut n = HashSet::new(); for x in s.iter() { n.insert(ArcIntern::from_ref(x as &str)); } n } println!( "ArcIntern::from {}", bench_gen_env(|| s1.clone(), mksetfrom) ); fn rmset(s: &mut (HashSet>, HashSet>)) { for x in s.1.iter() { s.0.remove(x); } } let s1: HashSet<_> = s1.iter().cloned().map(ArcIntern::new).collect(); let s2: HashSet<_> = s2.iter().cloned().map(ArcIntern::new).collect(); println!( "ArcIntern::compare/hash {}", bench_gen_env(|| (s1.clone(), s2.clone()), rmset) ); println!( "ArcIntern sort {}", bench_gen_env(|| s1.iter().cloned().collect::>(), |v| v.sort()) ); let value = ArcIntern::new("hello this is a pretty long string".to_string()); println!( "ArcIntern any eq {}", bench_gen_env( || s1.iter().cloned().collect::>(), |v| v.iter().any(|s| *s == value) ) ); } let i = ArcIntern::new(7i64); println!("ArcIntern::clone {}", bench(|| i.clone())); println!(); println!( "arc_interner::ArcIntern::new {}", bench_gen_env(rand::random::, |x| arc_interner::ArcIntern::new(*x)) ); println!( "arc_interner::ArcIntern::new {}", bench_gen_env(rand::random::, |x| arc_interner::ArcIntern::new(*x)) ); { fn mkset(s: &mut HashSet) -> HashSet> { let mut n = HashSet::new(); for x in s.iter() { n.insert(arc_interner::ArcIntern::new(x.clone())); } n } mkset(&mut s1.clone()); println!( "arc_interner::ArcIntern::new short {}", bench_gen_env(|| s_short.clone(), mkset) ); println!( "arc_interner::ArcIntern::new {}", bench_gen_env(|| s1.clone(), mkset) ); fn rmset( s: &mut ( HashSet>, HashSet>, ), ) { for x in s.1.iter() { s.0.remove(x); } } let s1: HashSet<_> = s1 .iter() .cloned() .map(arc_interner::ArcIntern::new) .collect(); let s2: HashSet<_> = s2 .iter() .cloned() .map(arc_interner::ArcIntern::new) .collect(); println!( "arc_interner::ArcIntern::compare/hash {}", bench_gen_env(|| (s1.clone(), s2.clone()), rmset) ); println!( "arc_interner::ArcIntern sort {}", bench_gen_env(|| s1.iter().cloned().collect::>(), |v| v.sort()) ); } let i = arc_interner::ArcIntern::new(7i64); println!( "arc_interner::ArcIntern::clone {}", bench(|| i.clone()) ); println!(); }