Skip to content
Snippets Groups Projects
Commit 47ba0de8 authored by STEVAN Antoine's avatar STEVAN Antoine :crab:
Browse files

improve performances by not shuffling vectors (dragoon/komodo!122)

in `./bins/inbreeding/`, this MR does
- refactor the "list item drawing" from `environment.rs` and `strategy.rs` into the `draw_unique_elements` function of new `random.rs` module
- use a `HashSet` to draw unique indices in the slice of "things" to draw from and then extracts the items corresponding to these indices

## results
```bash
use ./bins/inbreeding
use std bench

const PRNG_SEED = 0
const OPTS = {
    nb_bytes: (10 * 1_024),
    k: 10,
    n: 20,
    nb_measurements: 100,
    nb_scenarii: 10,
    measurement_schedule: 1,
    measurement_schedule_start: 2_000,
    max_t: 2_000,
    strategies: [ "single:5" ],
    environment: null,
}

def run [rev: string] {
    git co $rev

    inbreeding build

    let a = bench --rounds 5 {
        inbreeding run --options ($OPTS | update environment "fixed:0") --prng-seed $PRNG_SEED
    }
    let b = bench --rounds 5 {
        inbreeding run --options ($OPTS | update environment "fixed:1") --prng-seed $PRNG_SEED
    }

    {
        0: $a,
        1: $b,
    }
}

let main = run a29b511d
let mr = run fix-shuffle
```
```bash
let table = [
    [env, main, mr, improvement];

    ["fixed:0", $main."0".mean, $mr."0".mean, (($main."0".mean - $mr."0".mean) / $main."0".mean * 100)],
    ["fixed:1", $main."1".mean, $mr."1".mean, (($main."1".mean - $mr."1".mean) / $main."1".mean * 100)],
]

$table | to md --pretty
```

| env     | main                    | mr                      | improvement        |
| ------- | ----------------------- | ----------------------- | ------------------ |
| fixed:0 | 8sec 504ms 794µs 784ns | 6sec 353ms 206µs 645ns | 25.298530930431912 |
| fixed:1 | 727ms 648µs 292ns      | 639ms 443µs 782ns      | 12.12186037811795  |

the improvement is quite nice, even though not huge, but the code is cleaner anyways :pray:
parent a29b511d
No related branches found
No related tags found
No related merge requests found
use rand::{seq::SliceRandom, Rng, RngCore};
use rand::{Rng, RngCore};
use crate::random::draw_unique_elements;
#[derive(Debug, PartialEq)]
pub(super) enum Environment {
......@@ -14,28 +16,23 @@ impl Environment {
/// `update(things, rng)` is `things` with some elements potentially removed according to the
/// [`Environment`] type
pub(super) fn update<T: Clone>(&self, things: &[T], rng: &mut impl RngCore) -> Vec<T> {
let mut things = things.to_vec();
things.shuffle(rng);
match self {
Environment::Fixed { n } => things.iter().take(things.len() - n),
let nb_to_take = match self {
Environment::Fixed { n } => things.len() - n,
Environment::RandomFixed { p, n } => {
if rng.gen::<f64>() > *p {
return things;
return things.to_vec();
}
things.iter().take(things.len() - n)
things.len() - n
}
Environment::RandomDynamic { p, q } => {
if rng.gen::<f64>() > *p {
return things;
return things.to_vec();
}
things
.iter()
.take((things.len() as f64 * (1.0 - q)) as usize)
(things.len() as f64 * (1.0 - q)) as usize
}
}
.cloned()
.collect()
};
draw_unique_elements(things, nb_to_take, rng)
}
pub(super) fn from_str(s: &str) -> Result<Self, String> {
......
......@@ -9,9 +9,11 @@ use komodo::{
fec::{self, Shard},
linalg::Matrix,
};
use rand::{rngs::StdRng, seq::SliceRandom, Rng, RngCore, SeedableRng};
use rand::{rngs::StdRng, Rng, RngCore, SeedableRng};
use random::draw_unique_elements;
mod environment;
mod random;
mod strategy;
use crate::{environment::Environment, strategy::Strategy};
......@@ -38,16 +40,13 @@ fn measure_inbreeding<F: PrimeField>(
sty: &ProgressStyle,
rng: &mut impl RngCore,
) -> f64 {
let mut s: Vec<_> = shards.to_vec();
let mut count = 0;
let pb = mp.add(ProgressBar::new(nb_measurements as u64));
pb.set_style(sty.clone());
pb.set_message("measure");
for _ in 0..nb_measurements {
// get any k of the shards
s.shuffle(rng);
if fec::decode(s.iter().take(k).cloned().collect()).is_ok() {
if fec::decode(draw_unique_elements(shards, k, rng)).is_ok() {
count += 1;
}
pb.inc(1);
......
use rand::{Rng, RngCore};
use std::collections::HashSet;
fn draw_unique_indices(n: usize, vec_len: usize, rng: &mut impl RngCore) -> HashSet<usize> {
let mut indices = HashSet::new();
while indices.len() < n {
let idx = rng.gen_range(0..vec_len);
indices.insert(idx);
}
indices
}
pub(super) fn draw_unique_elements<T: Clone>(
things: &[T],
n: usize,
rng: &mut impl RngCore,
) -> Vec<T> {
let mut res = vec![];
for i in draw_unique_indices(n, things.len(), rng) {
res.push(things[i].clone());
}
res
}
use rand::{seq::SliceRandom, Rng, RngCore};
use rand::{Rng, RngCore};
use crate::random::draw_unique_elements;
#[derive(Debug, PartialEq)]
pub(super) enum Strategy {
......@@ -8,9 +10,6 @@ pub(super) enum Strategy {
impl Strategy {
pub(super) fn draw<T: Clone>(&self, things: &[T], rng: &mut impl RngCore) -> Vec<T> {
let mut things = things.to_vec();
things.shuffle(rng);
let nb_to_take = match self {
Self::Single { n } => *n,
Self::Double { p, n, m } => {
......@@ -22,7 +21,7 @@ impl Strategy {
}
};
things.iter().take(nb_to_take).cloned().collect()
draw_unique_elements(things, nb_to_take, rng)
}
pub(super) fn from_str(s: &str) -> Result<Self, String> {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment