Skip to content

Commit e49f49a

Browse files
committed
perf: reduce memory usage in profiling
Utilizes ThinStr in the ZendFrame to shrink memory. perf: pre-calculate buffer size in stalk walking
1 parent b0171fa commit e49f49a

File tree

10 files changed

+532
-363
lines changed

10 files changed

+532
-363
lines changed

Cargo.lock

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

profiling/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ chrono = { version = "0.4" }
2121
crossbeam-channel = { version = "0.5", default-features = false, features = ["std"] }
2222
datadog-alloc = { git = "https://github.com/DataDog/libdatadog", tag = "v10.0.0" }
2323
datadog-profiling = { git = "https://github.com/DataDog/libdatadog", tag = "v10.0.0" }
24+
datadog-thin-str = { version = "1", path = "../thin-str", features = ["std"] }
2425
ddcommon = { git = "https://github.com/DataDog/libdatadog", tag = "v10.0.0" }
2526
env_logger = { version = "0.11", default-features = false }
2627
indexmap = { version = "2.2" }
@@ -47,6 +48,10 @@ perfcnt = "0.8.0"
4748
name = "stack_walking"
4849
harness = false
4950

51+
[[bench]]
52+
name = "concatenation"
53+
harness = false
54+
5055
[features]
5156
default = ["allocation_profiling", "timeline", "exception_profiling"]
5257
allocation_profiling = []

profiling/benches/concatenation.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
use criterion::{criterion_group, criterion_main, Criterion};
2+
3+
#[allow(unused)]
4+
fn extract_function_name_v1(module_name: &[u8], class_name: &[u8], method_name: &[u8]) -> Vec<u8> {
5+
let mut buffer = Vec::<u8>::new();
6+
7+
if !module_name.is_empty() {
8+
buffer.extend_from_slice(module_name);
9+
buffer.push(b'|');
10+
}
11+
12+
if !class_name.is_empty() {
13+
buffer.extend_from_slice(class_name);
14+
buffer.extend_from_slice(b"::");
15+
}
16+
buffer.extend_from_slice(method_name);
17+
buffer
18+
}
19+
20+
#[allow(unused)]
21+
fn extract_function_name_v2(module_name: &[u8], class_name: &[u8], method_name: &[u8]) -> Vec<u8> {
22+
let opt_module_separator: &[u8] = if module_name.is_empty() { b"" } else { b"|" };
23+
let opt_class_separator: &[u8] = if class_name.is_empty() { b"" } else { b"::" };
24+
let cap = module_name.len()
25+
+ opt_module_separator.len()
26+
+ class_name.len()
27+
+ opt_class_separator.len()
28+
+ method_name.len();
29+
let mut buffer = Vec::<u8>::with_capacity(cap);
30+
31+
buffer.extend_from_slice(module_name);
32+
buffer.extend_from_slice(opt_module_separator);
33+
buffer.extend_from_slice(class_name);
34+
buffer.extend_from_slice(opt_class_separator);
35+
buffer.extend_from_slice(method_name);
36+
buffer
37+
}
38+
39+
fn bench_concatenation_userland(c: &mut Criterion) {
40+
c.bench_function("bench_concatenation_userland", |b| {
41+
b.iter(|| {
42+
for _ in 1..=100 {
43+
_ = std::hint::black_box(extract_function_name_v2(
44+
b"",
45+
b"Twig\\Template",
46+
b"displayWithErrorHandling",
47+
))
48+
}
49+
});
50+
});
51+
}
52+
53+
fn bench_concatenation_internal1(c: &mut Criterion) {
54+
c.bench_function("bench_concatenation_internal1", |b| {
55+
b.iter(|| {
56+
for _ in 1..=100 {
57+
_ = std::hint::black_box(extract_function_name_v2(
58+
b"dom",
59+
b"DOMDocumentFragment",
60+
b"__construct",
61+
))
62+
}
63+
});
64+
});
65+
}
66+
67+
fn bench_concatenation_internal2(c: &mut Criterion) {
68+
c.bench_function("bench_concatenation_internal2", |b| {
69+
b.iter(|| {
70+
for _ in 1..=100 {
71+
_ = std::hint::black_box(extract_function_name_v2(b"standard", b"", b"file"))
72+
}
73+
});
74+
});
75+
}
76+
77+
criterion_group!(
78+
benches,
79+
bench_concatenation_userland,
80+
bench_concatenation_internal1,
81+
bench_concatenation_internal2,
82+
);
83+
criterion_main!(benches);

profiling/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ mod logging;
66
mod pcntl;
77
pub mod profiling;
88
mod sapi;
9-
mod thin_str;
109
mod wall_time;
10+
mod well_known;
1111

1212
#[cfg(php_run_time_cache)]
1313
mod string_set;
@@ -313,7 +313,7 @@ extern "C" fn minit(_type: c_int, module_number: c_int) -> ZendResult {
313313
};
314314

315315
/* Currently, the engine is always copying this struct. Every time a new
316-
* PHP version is released, we should double check zend_register_extension
316+
* PHP version is released, we should double-check zend_register_extension
317317
* to ensure the address is not mutated nor stored. Well, hopefully we
318318
* catch it _before_ a release.
319319
*/

0 commit comments

Comments
 (0)