-
-
Notifications
You must be signed in to change notification settings - Fork 251
Remove static lifetime in StringName::from(&CStr)
#1307
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
Remove static lifetime in StringName::from(&CStr)
#1307
Conversation
API docs are being generated and will be shortly available at: https://godot-rust.github.io/docs/gdext/pr-1307 |
See also #531 (comment). In #1306 you mentioned:
Also, why would you use both
Please share that benchmark. Can you reproduce this with our existing |
Also, if we find that We already have |
In c++, using static StringName a = StringName("a", false);
static StringName b = StringName("b", true);
So we should use
It might make sense, but |
Benchmark in release mode: #[bench(repeat = 1000)]
fn string_name_cstr() -> StringName {
use godot::sys;
let c_str = c"c string";
unsafe {
StringName::new_with_string_uninit(|ptr| {
sys::interface_fn!(string_name_new_with_latin1_chars)(
ptr,
c_str.as_ptr(),
sys::conv::SYS_FALSE, // p_is_static
)
})
}
}
#[bench(repeat = 1000)]
fn string_name_cstr_static() -> StringName {
use godot::sys;
let c_str = c"c string";
let sname = unsafe {
StringName::new_with_string_uninit(|ptr| {
sys::interface_fn!(string_name_new_with_latin1_chars)(
ptr,
c_str.as_ptr(),
sys::conv::SYS_TRUE, // p_is_static
)
})
};
std::mem::forget(sname.clone());
sname
}
#[bench(repeat = 1000)]
fn string_name_cstr_static_correct() -> StringName {
use godot::sys;
let c_str = c"c string";
static SNAME: OnceLock<StringName> = OnceLock::new();
SNAME
.get_or_init(|| unsafe {
StringName::new_with_string_uninit(|ptr| {
sys::interface_fn!(string_name_new_with_latin1_chars)(
ptr,
c_str.as_ptr(),
sys::conv::SYS_TRUE, // p_is_static
)
})
})
.clone()
}
My explanation is that the 2nd (current method) leaks one, so Godot constructing it would be faster than the 1st, but this usage is incorrect. The 3rd is the right way. |
Thanks a lot! I'll try to have a detailed look at this on the weekend. 👍
But C++
The other string types don't offer such a constructor either, and C strings aren't a very common type in everyday Rust. You can easily create your own |
Found a way to create static StringName through macro ( #[bench(repeat = 10000)]
fn string_name_utf8() -> StringName {
StringName::from("a string")
}
#[bench(repeat = 10000)]
fn string_name_cstr() -> StringName {
use godot::sys;
let c_str = c"a string";
unsafe {
StringName::new_with_string_uninit(|ptr| {
sys::interface_fn!(string_name_new_with_latin1_chars)(
ptr,
c_str.as_ptr(),
sys::conv::SYS_FALSE, // p_is_static
)
})
}
}
#[bench(repeat = 10000)]
fn string_name_cstr_static() -> StringName {
use godot::sys;
let c_str = c"a string";
let sname = unsafe {
StringName::new_with_string_uninit(|ptr| {
sys::interface_fn!(string_name_new_with_latin1_chars)(
ptr,
c_str.as_ptr(),
sys::conv::SYS_TRUE, // p_is_static
)
})
};
std::mem::forget(sname.clone());
sname
}
#[bench(repeat = 10000)]
fn string_name_cstr_static_correct() -> StringName {
use godot::sys;
let c_str = c"a string";
static SNAME: OnceLock<StringName> = OnceLock::new();
SNAME
.get_or_init(|| unsafe {
StringName::new_with_string_uninit(|ptr| {
sys::interface_fn!(string_name_new_with_latin1_chars)(
ptr,
c_str.as_ptr(),
sys::conv::SYS_TRUE, // p_is_static
)
})
})
.clone()
}
#[bench(repeat = 10000)]
fn string_name_cstr_static_name_macro() -> StringName {
godot::builtin::static_name!(c"a string").clone()
}
|
64d4925
to
3b0f908
Compare
3b0f908
to
1ae588a
Compare
Thanks a lot! I'll need to look in detail at a later point. Regarding this PR, since it contains feature additions (which can happen without SemVer breakage), I'll postpone it after v0.4.0 release. The static creation macro will likely need some more discussion 🙂 From my earlier post:
Created #1316 to free the way for future improvements. |
Sorry, I accidentally merged this too soon. I will keep the code around, but unexpose The |
See #1306 and https://github.com/godotengine/godot/blob/9b50ea8adec073c891763f7c8c2844bf207cf103/core/string/string_name.cpp#L204-L259
Godot copys the cstr to
_data->name
, so it doesn't need static lifetime. Alsop_static
just marks it's static count and should not affect performance, it's useless for godot-rust now.