Skip to content

Commit d08b995

Browse files
committed
glib: Only optimize IntoGStr for String when capacity allows
Also add a bench to track the performance of GStr conversions.
1 parent 13e3079 commit d08b995

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

glib/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ memchr = "2.5.0"
4040
tempfile = "3"
4141
gir-format-check = "^0.1"
4242
trybuild2 = "1"
43+
criterion = "0.4.0"
4344

4445
[features]
4546
default = ["gio"]
@@ -65,3 +66,7 @@ features = ["dox"]
6566
[[test]]
6667
name = "subclass_compiletest"
6768
required-features = ["compiletests"]
69+
70+
[[bench]]
71+
name = "gstring"
72+
harness = false

glib/benches/gstring.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
2+
use glib::IntoGStr;
3+
4+
pub fn str_into_gstr(c: &mut Criterion) {
5+
c.bench_function("str as IntoGStr", |b| {
6+
b.iter(|| {
7+
"abcdefg".run_with_gstr(|g| {
8+
black_box(g);
9+
})
10+
})
11+
});
12+
}
13+
14+
pub fn string_into_gstr(c: &mut Criterion) {
15+
c.bench_function("String as IntoGStr", |b| {
16+
b.iter(|| {
17+
let mut s = String::from("abcdefg");
18+
s.shrink_to_fit();
19+
assert_eq!(s.capacity(), s.len());
20+
s.run_with_gstr(|g| {
21+
black_box(g);
22+
})
23+
})
24+
});
25+
}
26+
27+
pub fn string_with_capacity_into_gstr(c: &mut Criterion) {
28+
c.bench_function("String::with_capacity as IntoGStr", |b| {
29+
b.iter(|| {
30+
let mut s = String::with_capacity(100);
31+
s.push_str("abcdefg");
32+
assert!(s.capacity() > s.len());
33+
s.run_with_gstr(|g| {
34+
black_box(g);
35+
})
36+
})
37+
});
38+
}
39+
40+
criterion_group!(
41+
benches,
42+
str_into_gstr,
43+
string_into_gstr,
44+
string_with_capacity_into_gstr
45+
);
46+
criterion_main!(benches);

glib/src/gstring.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,9 +2318,17 @@ impl IntoGStr for &str {
23182318
impl IntoGStr for String {
23192319
#[inline]
23202320
fn run_with_gstr<T, F: FnOnce(&GStr) -> T>(mut self, f: F) -> T {
2321-
self.push('\0');
2322-
let gs = unsafe { GStr::from_utf8_with_nul_unchecked(self.as_bytes()) };
2323-
f(gs)
2321+
let len = self.len();
2322+
if len < self.capacity() {
2323+
self.reserve_exact(1);
2324+
self.push('\0');
2325+
let gs = unsafe { GStr::from_utf8_with_nul_unchecked(self.as_bytes()) };
2326+
f(gs)
2327+
} else if len < MAX_STACK_ALLOCATION {
2328+
self.as_str().run_with_gstr(f)
2329+
} else {
2330+
f(GString::from(self).as_gstr())
2331+
}
23242332
}
23252333
}
23262334

0 commit comments

Comments
 (0)