我应该使用什么数据类型作为缓冲区?
What data type should I use as a buffer?
我正在编写一个简单的聊天服务器,我想知道我应该为缓冲区使用什么数据类型。我在考虑 string
(对我来说这会很舒服),但是很多次我看到人们写道 string
不应该用作缓冲区(最好使用 vector<char>
)但总是这样吗?
在我的程序中,我想从客户端读取一些消息到缓冲区,将该数据发送到其他客户端并将该消息存储在数据库中。我使用 SQLite,所以 string
(跳过数据库初始化)它看起来像这样:
std::string buffer;
buffer.resize(1024);
// read some data into the buffer
socket.async_read_some(boost::asio::buffer(&buffer[0], 1024),
[this, self](boost::system::error_code ec, size_t length)
{
buffer.resize(length);
// do some other things with buffer - send to another user ...
std::string query = "INSERT INTO messages (message) VALUES (\"" + buffer "\")";
sqlite3_exec(database, query.c_str(), sql_callback, NULL, &err_msg);
}
如果我要使用 vector<char>
代替,我首先需要将其转换为字符串(或者可能有其他方法?)
那我应该用什么?
如果您的用例主要需要 "conversion" 到 std::string
,那么简单地使用 std::string
可能是个好主意。使用 std::string
作为字符缓冲区与 std::vector<char>
之间最明显的区别是前者被允许做一些魔术 短字符串优化 (取决于库供应商) .而后者不允许这样做。您的里程可能会有所不同。
If I was to use vector<char>
instead, I would firstly need to convert
it to a string (or maybe there is another way?)
是的,您必须像这样 std::vector<char>
到 std::string
"conversion":
std::string query = "INSERT INTO messages (message) VALUES (\"" + std::string(buffer.begin(), buffer.end()) + "\")";
通过一些工作,您可以避免使用 std::string::operator +
.[=] 缓冲区 "conversion" 和 连接创建临时(和多个内存分配) 26=]
std::string build_query(const char* left_string, std::size_t left_string_size,
const std::vector<char>& buffer,
const char* right_string, std::size_t right_string_size)
{
std::string query;
query.reserve(left_string_size + buffer.size() + right_string_size + 1);
query.append(left_string);
query.append(buffer.begin(), buffer.end());
query.append(right_string);
return query;
}
并像这样使用:
std::vector<char> buffer(24);
constexpr char left[] = "INSERT INTO messages (message) VALUES (\"";
constexpr char right[] = "\")";
std::string query = build_query( left, len(left), buffer, right, len(right) );
在此处查看完整示例:Live On Coliru
在较长的 运行 中,您可以更进一步,编写一些简洁的模板助手来涵盖从 std::vector<char>
构建查询字符串的更多一般情况。
至于性能,您将不得不衡量。虽然,虽然不是有效的性能衡量标准,但 GCC 和 Clang 实际上 emits fewer assembly build_query
指令比常规 "conversion" 指令。
我正在编写一个简单的聊天服务器,我想知道我应该为缓冲区使用什么数据类型。我在考虑 string
(对我来说这会很舒服),但是很多次我看到人们写道 string
不应该用作缓冲区(最好使用 vector<char>
)但总是这样吗?
在我的程序中,我想从客户端读取一些消息到缓冲区,将该数据发送到其他客户端并将该消息存储在数据库中。我使用 SQLite,所以 string
(跳过数据库初始化)它看起来像这样:
std::string buffer;
buffer.resize(1024);
// read some data into the buffer
socket.async_read_some(boost::asio::buffer(&buffer[0], 1024),
[this, self](boost::system::error_code ec, size_t length)
{
buffer.resize(length);
// do some other things with buffer - send to another user ...
std::string query = "INSERT INTO messages (message) VALUES (\"" + buffer "\")";
sqlite3_exec(database, query.c_str(), sql_callback, NULL, &err_msg);
}
如果我要使用 vector<char>
代替,我首先需要将其转换为字符串(或者可能有其他方法?)
那我应该用什么?
如果您的用例主要需要 "conversion" 到 std::string
,那么简单地使用 std::string
可能是个好主意。使用 std::string
作为字符缓冲区与 std::vector<char>
之间最明显的区别是前者被允许做一些魔术 短字符串优化 (取决于库供应商) .而后者不允许这样做。您的里程可能会有所不同。
If I was to use
vector<char>
instead, I would firstly need to convert it to a string (or maybe there is another way?)
是的,您必须像这样 std::vector<char>
到 std::string
"conversion":
std::string query = "INSERT INTO messages (message) VALUES (\"" + std::string(buffer.begin(), buffer.end()) + "\")";
通过一些工作,您可以避免使用 std::string::operator +
.[=] 缓冲区 "conversion" 和 连接创建临时(和多个内存分配) 26=]
std::string build_query(const char* left_string, std::size_t left_string_size,
const std::vector<char>& buffer,
const char* right_string, std::size_t right_string_size)
{
std::string query;
query.reserve(left_string_size + buffer.size() + right_string_size + 1);
query.append(left_string);
query.append(buffer.begin(), buffer.end());
query.append(right_string);
return query;
}
并像这样使用:
std::vector<char> buffer(24);
constexpr char left[] = "INSERT INTO messages (message) VALUES (\"";
constexpr char right[] = "\")";
std::string query = build_query( left, len(left), buffer, right, len(right) );
在此处查看完整示例:Live On Coliru
在较长的 运行 中,您可以更进一步,编写一些简洁的模板助手来涵盖从 std::vector<char>
构建查询字符串的更多一般情况。
至于性能,您将不得不衡量。虽然,虽然不是有效的性能衡量标准,但 GCC 和 Clang 实际上 emits fewer assembly build_query
指令比常规 "conversion" 指令。