tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

solver.rs (3431B)


      1 use criterion::criterion_group;
      2 use criterion::criterion_main;
      3 use criterion::Criterion;
      4 
      5 use futures::stream::Collect;
      6 use futures::stream::FuturesOrdered;
      7 use futures::StreamExt;
      8 use l10nregistry_tests::solver::get_scenarios;
      9 use l10nregistry::solver::{AsyncTester, ParallelProblemSolver, SerialProblemSolver, SyncTester};
     10 use std::future::Future;
     11 use std::pin::Pin;
     12 use std::task::{Context, Poll};
     13 
     14 pub struct MockTester {
     15    values: Vec<Vec<bool>>,
     16 }
     17 
     18 impl SyncTester for MockTester {
     19    fn test_sync(&self, res_idx: usize, source_idx: usize) -> bool {
     20        self.values[res_idx][source_idx]
     21    }
     22 }
     23 
     24 pub struct SingleTestResult(bool);
     25 
     26 impl Future for SingleTestResult {
     27    type Output = bool;
     28 
     29    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
     30        self.0.into()
     31    }
     32 }
     33 
     34 pub type ResourceSetStream = Collect<FuturesOrdered<SingleTestResult>, Vec<bool>>;
     35 pub struct TestResult(ResourceSetStream);
     36 
     37 impl std::marker::Unpin for TestResult {}
     38 
     39 impl Future for TestResult {
     40    type Output = Vec<bool>;
     41 
     42    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
     43        let pinned = Pin::new(&mut self.0);
     44        pinned.poll(cx)
     45    }
     46 }
     47 
     48 impl AsyncTester for MockTester {
     49    type Result = TestResult;
     50 
     51    fn test_async(&self, query: Vec<(usize, usize)>) -> Self::Result {
     52        let futures = query
     53            .into_iter()
     54            .map(|(res_idx, source_idx)| SingleTestResult(self.test_sync(res_idx, source_idx)))
     55            .collect::<Vec<_>>();
     56        TestResult(futures.into_iter().collect::<FuturesOrdered<_>>().collect())
     57    }
     58 }
     59 
     60 struct TestStream<'t> {
     61    solver: ParallelProblemSolver<MockTester>,
     62    tester: &'t MockTester,
     63 }
     64 
     65 impl<'t> TestStream<'t> {
     66    pub fn new(solver: ParallelProblemSolver<MockTester>, tester: &'t MockTester) -> Self {
     67        Self { solver, tester }
     68    }
     69 }
     70 
     71 impl<'t> futures::stream::Stream for TestStream<'t> {
     72    type Item = Vec<usize>;
     73 
     74    fn poll_next(
     75        mut self: std::pin::Pin<&mut Self>,
     76        cx: &mut std::task::Context<'_>,
     77    ) -> std::task::Poll<Option<Self::Item>> {
     78        let tester = self.tester;
     79        let solver = &mut self.solver;
     80        let pinned = std::pin::Pin::new(solver);
     81        pinned
     82            .try_poll_next(cx, tester, false)
     83            .map(|v| v.ok().flatten())
     84    }
     85 }
     86 
     87 fn solver_bench(c: &mut Criterion) {
     88    let scenarios = get_scenarios();
     89 
     90    let mut group = c.benchmark_group("solver");
     91 
     92    for scenario in scenarios {
     93        let tester = MockTester {
     94            values: scenario.values.clone(),
     95        };
     96 
     97        group.bench_function(&format!("serial/{}", &scenario.name), |b| {
     98            b.iter(|| {
     99                let mut gen = SerialProblemSolver::new(scenario.width, scenario.depth);
    100                while let Ok(Some(_)) = gen.try_next(&tester, false) {}
    101            })
    102        });
    103 
    104        {
    105            let rt = tokio::runtime::Runtime::new().unwrap();
    106 
    107            group.bench_function(&format!("parallel/{}", &scenario.name), |b| {
    108                b.iter(|| {
    109                    let gen = ParallelProblemSolver::new(scenario.width, scenario.depth);
    110                    let mut t = TestStream::new(gen, &tester);
    111                    rt.block_on(async { while let Some(_) = t.next().await {} });
    112                })
    113            });
    114        }
    115    }
    116    group.finish();
    117 }
    118 
    119 criterion_group!(benches, solver_bench);
    120 criterion_main!(benches);