因此,在组合字符串时,通常会有常量组件,例如:
std::string s;
s += initial_string;
s += "const string";
s += terminating_string;
这只是一个演示,字符串操作可能会更加复杂和深入。因此,在执行const部分时,实现最终“不知道”长度并有效地对其进行strlen()
。显然这是一种浪费,因为在编译时已知长度。我已经测试过用这个替换const字符串部分要快得多(无论出于何种原因,在x64中更多):
s.append("const string",12);
实际计算角色是烦人的,耗时且容易出错的,所以这样做会更好一点:
s.append("const string",sizeof("const string")-1);
这仍然有点容易出错(即更改第一部分但忘记更改第二部分)所以宏可以帮助这个:
#define strnsizeof(s) s,sizeof(s)-1
s.append(strnsizeof("const string"));
问题1:任何人都有更好/更清洁的解决方案吗?
我还有一个扩展的字符串类,我使用<<
运算符来连接字符串和各种其他对象类型。类似的问题在这里,这很好,干净(对我来说):
s << initial_string << "const string" << terminating_string;
当我有一个运算符用于我自己的对象类型(其长度是一个组件)时,追加操作快速而简单,但当它再次获得const char *
时,我的长度均匀虽然它在编译时是不变的。所以我可以通过创建一个小const char *
和长度的小结构来加快速度:
s << initial_string
<< MyStr::ConstBuf(strnsizeof("const string"))
<< terminating_string;
男孩变得丑陋。所以我也可以解决这个问题,例如:
#define MyStrConst(s) MyStr::ConstBuf(s,sizeof(s)-1)
s << initial_string
<< MyStrConst("const string")
<< terminating_string;
更好,但不是很好。
问题2:有人比封装常量字符串有更好/更清晰的解决方案吗?
答案 0 :(得分:3)
对该问题的评论产生了如下模板:
template<size_t SZ> std::string& operator<<( std::string &s, const char(&arr)[SZ] ) {
s.append( arr, SZ-1 );
return s;
}
因此,在执行以下操作时,不使用s += "const string"
模板:
s << "const string"
此外,我能够更新我的扩展字符串类,以便以下使用模板来获得常量大小:
s << initial_string << "const string" << terminating_string;
编辑:这不能按预期工作:
typedef struct { char buffer[32]; } ST;
ST st = { "1234" };
s << st.buffer; // results in s with size 31!
这可以通过非const模板解决,例如:
template<size_t SZ> std::string& operator<<( std::string &s, char(&arr)[SZ] ) {
s.append( arr ); // NOTE not using SZ here so a strlen happens
return s;
}
现在:
s << st.buffer; // results in s with size 4
除了:
const ST cst = &st;
s << cst.buffer; // results in s with size 31 again...
buffer
位于class
时出现同样的问题,正如您所期望的那样。
答案 1 :(得分:2)
写信给您的编译器制造商,并询问他们为什么不针对这种情况进行优化。然后,希望他们将常量字符串连接添加到优化列表中,每个人的代码都会更快,而无需做任何事情!
这将是我最喜欢的解决方案。
答案 2 :(得分:0)
仅仅是:
const std::string const_string("const string");
std::string s;
s += initial_string;
s += const_string;
s += terminating_string;
答案 3 :(得分:0)
我无法访问MSVC编译器。保留足够大的缓冲区会改善性能吗?
沿着这些方向的东西
#include <iostream>
#include <string>
using namespace std;
string fast_concat(string s, const string& terminating_string) {
static const string const_string("const string");
s.reserve(s.size() + const_string.size() + terminating_string.size());
s.append(const_string);
s.append(terminating_string);
return s;
}
int main() {
cout << fast_concat("initial_string, ", ", terminating string") << endl;
}
(我希望在按值捕获第一个参数时以及在返回结果时进行移动。)
答案 4 :(得分:0)
以下是使用模板
在编译时获取strlen
的方法
#include <iostream>
#include <string>
using namespace std;
template <size_t N>
void concat_char_array(string& s, const char (&array)[N]) {
s.append(array, N-1);
}
string fast_concat(string s, const string& terminating_string) {
concat_char_array(s, "const string");
s.append(terminating_string);
return s;
}
int main() {
cout << fast_concat("initial string, ", ", terminating string") << endl;
}
它应该和宏一样快。