use criterion::*;
use genetic_algorithm::chromosome::Chromosome;
use genetic_algorithm::fitness::placeholders::{
CountTrue, CountTrueWithSleep, Countdown, CountdownNoisy, SumGenes,
};
use genetic_algorithm::fitness::Fitness;
use genetic_algorithm::genotype::{BinaryGenotype, Genotype, ListGenotype, RangeGenotype};
use genetic_algorithm::population::Population;
use rand::prelude::*;
use rand::rngs::SmallRng;
use thread_local::ThreadLocal;
pub fn placeholders_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("fitness-placeholders");
group.bench_function("count_true", |b| {
let genotype = BinaryGenotype::builder()
.with_genes_size(1000)
.build()
.unwrap();
let chromosome = Chromosome::new(vec![true; 1000]);
let mut fitness = CountTrue;
b.iter(|| fitness.calculate_for_chromosome(black_box(&chromosome), &genotype))
});
group.bench_function("sum_genes_with_precision", |b| {
let genotype = RangeGenotype::builder()
.with_genes_size(1000)
.with_allele_range(0.0..=1.0)
.build()
.unwrap();
let chromosome = Chromosome::new(vec![1.0; 1000]);
let mut fitness = SumGenes::new_with_precision(1e-5);
b.iter(|| fitness.calculate_for_chromosome(black_box(&chromosome), &genotype))
});
group.bench_function("sum_genes", |b| {
let genotype = ListGenotype::builder()
.with_genes_size(1000)
.with_allele_list((0_u32..100_u32).collect())
.build()
.unwrap();
let chromosome = Chromosome::<u32>::new(vec![1; 1000]);
let mut fitness = SumGenes::new();
b.iter(|| fitness.calculate_for_chromosome(black_box(&chromosome), &genotype))
});
group.bench_function("countdown", |b| {
let genotype = ListGenotype::builder()
.with_genes_size(1000)
.with_allele_list((0_u32..100_u32).collect())
.build()
.unwrap();
let chromosome = Chromosome::<u32>::new(vec![1; 1000]);
let mut fitness = Countdown::new(usize::MAX);
b.iter(|| fitness.calculate_for_chromosome(black_box(&chromosome), &genotype))
});
group.bench_function("countdown_with_noise", |b| {
let genotype = ListGenotype::builder()
.with_genes_size(1000)
.with_allele_list((0_u32..100_u32).collect())
.build()
.unwrap();
let chromosome = Chromosome::<u32>::new(vec![1; 1000]);
let mut fitness = CountdownNoisy::new(usize::MAX - 10_000, 1000, 1..10_000);
b.iter(|| fitness.calculate_for_chromosome(black_box(&chromosome), &genotype))
});
}
pub fn multithreading_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("fitness-multithreading");
let mut rng = SmallRng::from_entropy();
let genotype = BinaryGenotype::builder()
.with_genes_size(100)
.build()
.unwrap();
let chromosomes = (0..100)
.map(|_| Chromosome::new(genotype.random_genes_factory(&mut rng)))
.collect();
let population = Population::new(chromosomes, true);
group.sample_size(30);
group.bench_function("fitness-CountTrueWithSleep-single-threaded", |b| {
let mut fitness = CountTrueWithSleep::new(1000, true);
b.iter_batched(
|| population.clone(),
|mut data| {
fitness.call_for_population(&mut data, &genotype, None, None);
},
BatchSize::SmallInput,
);
});
let fitness_thread_local = Some(ThreadLocal::new());
group.sample_size(300);
group.bench_function("fitness-CountTrueWithSleep-multi-threaded", |b| {
let mut fitness = CountTrueWithSleep::new(1000, true);
b.iter_batched(
|| population.clone(),
|mut data| {
fitness.call_for_population(
&mut data,
&genotype,
fitness_thread_local.as_ref(),
None,
);
},
BatchSize::SmallInput,
);
});
}
criterion_group!(benches, placeholders_benchmark, multithreading_benchmark);
criterion_main!(benches);