-
Notifications
You must be signed in to change notification settings - Fork 24
Benchmark #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Anybody any experience to this? |
I've tried to do some bench. In my benches it looks like this:
Left side ascii, right side std... And if there are more method-calls, instead each time an instantiation, ascii seems to become little bit faster. I think this has to do with compiler optimizations based on the
The #![feature(test)]
#![allow(unused_crate_dependencies)]
use std::{convert::TryFrom, fs, io::BufRead};
use ascii::{AsAsciiStr, AsciiStr, AsciiString};
extern crate test;
struct HeaderFieldValue<T>(T);
impl TryFrom<&[u8]> for HeaderFieldValue<AsciiString> {
type Error = ();
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self(AsciiString::from_ascii(value).unwrap()))
}
}
impl TryFrom<&[u8]> for HeaderFieldValue<String> {
type Error = ();
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self(String::from_utf8(value.to_vec()).unwrap()))
}
}
fn load_lorem_ipsum() -> Vec<Vec<u8>> {
let mut data = Vec::new();
let file = fs::read("./benches/lorem_ipsum.txt").unwrap();
for l in file.lines() {
let l = l.unwrap();
if !l.is_empty() {
data.push(l.as_bytes().to_vec());
}
}
assert_eq!(data.len(), 20);
assert!(data[0].len() > 10);
data
}
#[allow(clippy::inline_always)]
#[inline(always)]
fn create_header_field_value_ascii(data: &Vec<u8>) -> HeaderFieldValue<AsciiString> {
HeaderFieldValue::try_from(data.as_slice()).unwrap()
}
#[allow(clippy::inline_always)]
#[inline(always)]
fn create_header_field_value_std(data: &Vec<u8>) -> HeaderFieldValue<String> {
HeaderFieldValue::try_from(data.as_slice()).unwrap()
}
#[allow(clippy::inline_always)]
#[inline(always)]
fn task_ascii(data: &Vec<Vec<u8>>, rounds: usize) -> Vec<HeaderFieldValue<AsciiString>> {
let mut fields = Vec::new();
for d in data {
let hfv = create_header_field_value_ascii(d);
fields.push(hfv);
}
for _ in 0..rounds {
for field in &fields {
let s = field.0.as_ascii_str().unwrap();
let mut s_clone = s.to_ascii_string();
let splits = s_clone.split(ascii::AsciiChar::Space);
let mut count = 0;
for split in splits {
count += split.len();
}
let _ = std::hint::black_box(count);
s_clone.push_str(AsciiStr::from_ascii(b"Hello World").unwrap());
s_clone.insert_str(0, AsciiStr::from_ascii(b"Start the race").unwrap());
s_clone.shrink_to_fit();
let xvalue = s_clone.remove(3);
let _ = std::hint::black_box(xvalue);
let f = format!("s: {s_clone}");
let _ = std::hint::black_box(f);
}
}
fields
}
#[allow(clippy::inline_always)]
#[inline(always)]
fn task_std(data: &Vec<Vec<u8>>, rounds: usize) -> Vec<HeaderFieldValue<String>> {
let mut fields = Vec::new();
for d in data {
let hfv = create_header_field_value_std(d);
fields.push(hfv);
}
for _ in 0..rounds {
for field in &fields {
let s = field.0.as_str();
let mut s_clone = s.to_string();
let splits = s_clone.split(' ');
let mut count = 0;
for split in splits {
count += split.len();
}
let _ = std::hint::black_box(count);
s_clone.push_str(std::str::from_utf8(b"Hello World").unwrap());
s_clone.insert_str(0, std::str::from_utf8(b"Start the race").unwrap());
s_clone.shrink_to_fit();
let xvalue = s_clone.remove(3);
let _ = std::hint::black_box(xvalue);
let f = format!("s: {s_clone}");
let _ = std::hint::black_box(f);
}
}
fields
}
const ROUNDS: usize = 10;
const INNER_ROUNDS: usize = 500;
#[bench]
fn ascii_string_bench(bencher: &mut test::Bencher) {
let data = load_lorem_ipsum();
bencher.iter(|| {
for _ in 0..ROUNDS {
let fields = task_ascii(&data, INNER_ROUNDS);
let _fields = std::hint::black_box(fields);
}
});
}
#[bench]
fn std_string_bench(bencher: &mut test::Bencher) {
let data = load_lorem_ipsum();
bencher.iter(|| {
for _ in 0..ROUNDS {
let fields = task_std(&data, INNER_ROUNDS);
let _fields = std::hint::black_box(fields);
}
});
} |
Dear all,
Is there any evidence if this crate is faster than Rust std String (for ASCII)?
Did anybody do benchmark or something?
Generally I think there should be a section in README about why should somebody use this crate, for ASCII strings.
The text was updated successfully, but these errors were encountered: