简体   繁体   English

我应该使用什么数据类型作为缓冲区?

[英]What data type should I use as a buffer?

I'm writing a simple chat server and I'm wondering what data type should I use for a buffer. 我正在写一个简单的聊天服务器,我想知道我应该为缓冲区使用什么数据类型。 I was thinking about string (which would be quite comfortable in my case), however many times I saw people writing that string should not be used as a buffer (better to use vector<char> ) but is it always the case? 我正在考虑string (在我的情况下会非常舒服),但是很多次我看到写string人不应该用作缓冲区(最好使用vector<char> )但总是这样吗?

In my program I would like to read some message from the client into a buffer, send that data to some other client and also store that message in database. 在我的程序中,我想从客户端读取一些消息到缓冲区,将该数据发送到其他客户端,并将该消息存储在数据库中。 I use SQLite so, with string (skipping db initialization) it would look like this: 我使用SQLite,使用string (跳过db初始化),它看起来像这样:

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);
}

If I was to use vector<char> instead, I would firstly need to convert it to a string (or maybe there is another way?) 如果我要使用vector<char> ,我首先需要将其转换为字符串(或者可能还有另一种方式?)

So what should I use? 那我该怎么用?

If your use-case mostly requires some "conversion" to std::string , then it may be a good idea to simply use std::string . 如果你的用例主要需要对std::string一些“转换”,那么简单地使用std::string可能是个好主意。 The most obvious difference between using std::string as a character buffer vs std::vector<char> is that the former is permitted to do some magic Short String Optimization (depends on library vendor). 使用std::string作为字符缓冲区与std::vector<char>之间最明显的区别是前者被允许做一些神奇的短字符串优化 (取决于库供应商)。 While the latter isn't permitted to do so. 虽然后者不允许这样做。 Your Mileage May Vary. 你的旅费可能会改变。

If I was to use vector<char> instead, I would firstly need to convert it to a string (or maybe there is another way?) 如果我要使用vector<char> ,我首先需要将其转换为字符串(或者可能还有另一种方式?)

Yes you would have to do a std::vector<char> to std::string "conversion" like this: 是的你必须像这样对std::vector<char>进行std::string “转换”:

std::string query = "INSERT INTO messages (message) VALUES (\"" + std::string(buffer.begin(), buffer.end()) + "\")";

With some work, you can avoid creating temporaries (and multiple memory allocations) resulting from both buffer "conversion" and concatenation using std::string::operator + . 通过一些工作,您可以避免使用缓冲区“转换” 使用std::string::operator +连接产生临时(和多个内存分配)。

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;
}

And use like: 并使用如下:

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) );

See a full example here: Live On Coliru 在这里查看完整示例: Live On Coliru

On the long run, you could go further and write some neat template helpers to cover more general cases of building up query string from std::vector<char> . 从长远来看,你可以进一步编写一些简洁的模板助手,以涵盖从std::vector<char>构建查询字符串的更一般情况。

As for performance, you will have to measure. 至于表现,你将不得不衡量。 Though, while not a valid measure of performance, GCC and Clang actually emits fewer assembly instructions for build_query than the regular "conversion". 虽然GCC和Clang虽然不是一种有效的性能测量方法,但实际上比常规“转换” 发出的 build_query 组装指令更少

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM