sark 0.13.0

Simple Asynchronous Rust webKit - Server
Documentation
use std::hint::black_box;

use criterion::{Criterion, criterion_group, criterion_main};
use o3::buffer::{Bytes, Retained};
use sark::service::RouteRequestImpl;
use sark_core::http::codec::RequestLine;

#[sark_gen::request(ordered)]
struct TwoQuery {
    #[query("nonce", default = "none")]
    nonce: Bytes<Retained>,
    #[query("lane", default = "none")]
    lane: Bytes<Retained>,
}

#[sark_gen::request(ordered)]
struct ThreeQuery {
    #[query("expand", default = "none")]
    expand: Bytes<Retained>,
    #[query("nonce", default = "none")]
    nonce: Bytes<Retained>,
    #[query("lane", default = "none")]
    lane: Bytes<Retained>,
}

fn fixtures() -> Vec<(&'static str, &'static [u8])> {
    vec![
        (
            "json",
            b"GET /json HTTP/1.1\r\nHost: x\r\nAccept: */*\r\n\r\n",
        ),
        ("db", b"GET /db HTTP/1.1\r\nHost: x\r\n\r\n"),
        (
            "user_param",
            b"GET /user/12345 HTTP/1.1\r\nHost: x\r\n\r\n",
        ),
        (
            "fat",
            b"GET /json HTTP/1.1\r\nHost: example.com\r\nAccept: */*\r\nAccept-Encoding: gzip\r\nUser-Agent: bench/1.0\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nCache-Control: no-cache\r\nX-Request-Id: abcdef\r\nX-Forwarded-For: 10.0.0.1\r\nReferer: http://x/y\r\nCookie: a=b\r\nPragma: no-cache\r\n\r\n",
        ),
    ]
}

fn parse_line(buf: &[u8]) -> Option<(usize, usize, usize)> {
    let head = RequestLine::parse(buf).ok().flatten()?;
    Some((head.method.len(), head.target.len(), head.headers_start))
}

fn bench_head(c: &mut Criterion) {
    let mut group = c.benchmark_group("head_parse");
    for (name, buf) in fixtures() {
        group.bench_function(name, |b| {
            b.iter(|| black_box(parse_line(black_box(buf))));
        });
    }
    group.finish();

    let mut query = c.benchmark_group("query_parse");
    let two = b"nonce=74828&lane=6";
    query.bench_function("ordered_two", |b| {
        b.iter(|| {
            let mut headers = TwoQueryHeadersRaw::default();
            <TwoQuery as RouteRequestImpl>::parse_query_raw(
                &mut headers,
                black_box(two),
                0..two.len(),
            )
            .unwrap();
            black_box(headers);
        });
    });
    let three = b"expand=items&nonce=74828&lane=6";
    query.bench_function("ordered_three", |b| {
        b.iter(|| {
            let mut headers = ThreeQueryHeadersRaw::default();
            <ThreeQuery as RouteRequestImpl>::parse_query_raw(
                &mut headers,
                black_box(three),
                0..three.len(),
            )
            .unwrap();
            black_box(headers);
        });
    });
    query.finish();
}

criterion_group!(benches, bench_head);
criterion_main!(benches);