【发布时间】:2026-02-10 23:30:02
【问题描述】:
我正在开发包含大量静态字符串的库。为了稍微优化运行时,这应该从以空结尾的字符串(经典的 C 样式字符数组)更改为预先知道长度的结构,例如 std::string 或 std::string_view 或自定义指针+长度对。 std::string 众所周知且用途广泛,但如果 Small-String-Optimization 不适用,它的缺点是占用空间大(x64 上至少 32 位)加上 VM 开销(堆和运行时成本),这会影响我的大部分数据。 string_view 听起来是最好的选择,只要我可以确定数据是空终止的(尽管 string_view 本身没有这样的保证,但可以通过约定来减轻风险)。
仍然很重要的问题:现代编译器是否在不使用内部 strlen 的情况下预初始化 string_view,即具有恒定复杂性而不是 O^(n)?如果有,是否保留空终止符?
当然,我可以添加一些宏来初始化string_views,但这会很麻烦。比如:
#define foo(buf) foo, (sizeof(foo)-1)
const string_view svMyVar(foo("original C-string value"));
我希望编译器会为我简化。
【问题讨论】:
-
您的意思是写
#define foo(buf) buf, (sizeof(buf)-1)吗? -
您也可以存储为
char const str[] = "foobar";,让编译器确定数组的大小,您可以通过类型系统查询。这在理论上允许 ctorstring_view(char(&)[N])保证在编译时计算字符串“长度”,但标准库中没有这样的 ctor。 -
除此之外,还有
"foobar"sv使用用户定义的文字,编译器再次知道字符串长度并将其传递给函数operator""(char const*, size_t)。最重要的是,您可以拥有constexpr string_view x = ...;,它应该由任何合理的优化编译器在编译时初始化。 -
你可以在这里玩一下:compiler-explorer.com/z/bc6s847Pr 正如预期的那样,
constexpr导致编译时字符串长度“计算”,即使没有优化,可变块范围string_view得到他们的字符串长度计算在编译时已在-O1解决。使用sv用户定义的文字也可以在编译时解析长度而不进行优化。
标签: c++