Enable CowData/String in constexpr environment#108788
Enable CowData/String in constexpr environment#108788YYF233333 wants to merge 9 commits intogodotengine:masterfrom
CowData/String in constexpr environment#108788Conversation
40050bf to
b05c112
Compare
2b14769 to
8c092ac
Compare
8c092ac to
d5cac55
Compare
|
Hi, this is an interesting proposition that we've been discussing a few times! I have also made an attempt at implementing it, which you may want to have a look at: https://github.com/Ivorforce/godot/tree/constexpr-string I don't exactly remember the outcome, but I believe the main problem I encountered was that users needed to use a custom macro ( |
Yes, I encountered the same issue. I believe the key here is that we must somehow write |
a1a0863 to
c2b71f0
Compare
c2b71f0 to
7a42159
Compare
TLDR: This PR allows you to write
constexpr Stringandconstexpr StringName.Overview
Enable the usage of
CowData/String/StringNamewith string literals at compile time.This is achieved by constructing a static
char32_tbuffer with the same layoutCowDataget at runtime.refcountis assigned a big enough value (currentlyUINT32_MAX) so the buffer will never be freed. With aconstinitbuffer like this we can create various pointer-like types (String/StringName).Implementation
CowBuffer: a staticchar32_tbuffer withrefcountandsizeattached at front. Some tricks are used to ensure it can be evaluated in constexpr environment. (I don't know if I accidentally introduce any forbidden STL stuff, please tell me if you find anything inappropriate.)ComptimeString: convenient wrapper. Instead of writingstatic constinit _buf = CowBuffer("str"); constexpr String s = CowData<char32_t>(buf);, we can just useComptimeString<"str">().valueCowData/String/StringNametoconstexpr. Memory alloc related codes are bypassed usingstd::is_constant_evaluated().ComptimeStringName: similar toComptimeString, but also handleStringName::_Dataregistration.Usage
GDCLASS/GDVIRTUAL: Replacestatic String,static StringName,"string literals"with their comptime conterparts.SNAME: Replace lambda withComptimeStringName.StringName("literals", true): Replace withComptimeStringName.Benchmark
Old
Binary Size (
production=yes target=template_release use_llvm=yes)Benchmarks (5 runs average)
Result (quite chaotic and not very consistent)
raw data:
ma.jsonl.txt
pr.jsonl.txt
New:
Benchmarks (5 runs average)
Result
raw data:
ma2.jsonl.txt
pr2.jsonl.txt
Notes
The main merit you could expect from this PR is reduced binary size, as it's unlikely that we’ll repeatedly create
String/StringNamefrom string literals on hot paths (you can always cache the results). However, compile-time computation can eliminate the constructor code forString/StringName, reducing the size of the.textsection, and in some cases, it can also replace more complex templates.TODO
Vectorwith simple types, but I haven't find usecases yet.StringNameproperly.