Skip to content

Commit

Permalink
Merge pull request #1034 from jf2048/string-into-gstr-perf
Browse files Browse the repository at this point in the history
glib: Only optimize `IntoGStr` for `String` when capacity allows
  • Loading branch information
sdroege authored Mar 1, 2023
2 parents 292f9a3 + d08b995 commit 1f762ec
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
5 changes: 5 additions & 0 deletions glib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ memchr = "2.5.0"
tempfile = "3"
gir-format-check = "^0.1"
trybuild2 = "1"
criterion = "0.4.0"

[features]
default = ["gio"]
Expand All @@ -65,3 +66,7 @@ features = ["dox"]
[[test]]
name = "subclass_compiletest"
required-features = ["compiletests"]

[[bench]]
name = "gstring"
harness = false
46 changes: 46 additions & 0 deletions glib/benches/gstring.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use glib::IntoGStr;

pub fn str_into_gstr(c: &mut Criterion) {
c.bench_function("str as IntoGStr", |b| {
b.iter(|| {
"abcdefg".run_with_gstr(|g| {
black_box(g);
})
})
});
}

pub fn string_into_gstr(c: &mut Criterion) {
c.bench_function("String as IntoGStr", |b| {
b.iter(|| {
let mut s = String::from("abcdefg");
s.shrink_to_fit();
assert_eq!(s.capacity(), s.len());
s.run_with_gstr(|g| {
black_box(g);
})
})
});
}

pub fn string_with_capacity_into_gstr(c: &mut Criterion) {
c.bench_function("String::with_capacity as IntoGStr", |b| {
b.iter(|| {
let mut s = String::with_capacity(100);
s.push_str("abcdefg");
assert!(s.capacity() > s.len());
s.run_with_gstr(|g| {
black_box(g);
})
})
});
}

criterion_group!(
benches,
str_into_gstr,
string_into_gstr,
string_with_capacity_into_gstr
);
criterion_main!(benches);
14 changes: 11 additions & 3 deletions glib/src/gstring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2318,9 +2318,17 @@ impl IntoGStr for &str {
impl IntoGStr for String {
#[inline]
fn run_with_gstr<T, F: FnOnce(&GStr) -> T>(mut self, f: F) -> T {
self.push('\0');
let gs = unsafe { GStr::from_utf8_with_nul_unchecked(self.as_bytes()) };
f(gs)
let len = self.len();
if len < self.capacity() {
self.reserve_exact(1);
self.push('\0');
let gs = unsafe { GStr::from_utf8_with_nul_unchecked(self.as_bytes()) };
f(gs)
} else if len < MAX_STACK_ALLOCATION {
self.as_str().run_with_gstr(f)
} else {
f(GString::from(self).as_gstr())
}
}
}

Expand Down

0 comments on commit 1f762ec

Please sign in to comment.