Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

代价较高的 std::shared_ptr<std::iostream> #12

Closed
yanminhui opened this issue Apr 26, 2019 · 4 comments
Closed

代价较高的 std::shared_ptr<std::iostream> #12

yanminhui opened this issue Apr 26, 2019 · 4 comments

Comments

@yanminhui
Copy link

yanminhui commented Apr 26, 2019

提供的有关上传数据的接口参数为 std::shared_ptr<std::iostream>,如果遇上传的数据来源于程序产生,那么使用如下方式解决:

using byte_t = unsigned char;

bool COssUpload::UploadPart(int iPartNumber
                          , byte_t const* pkbyContent
                          , std::uint64_t ui64ContentLength
                          , COssError& rError)
{
    std::string const kstrContent((char*)pkbyContent
                                , static_cast<std::string::size_type>(ui64ContentLength));
    std::shared_ptr<std::iostream> piosContent = std::make_shared<std::stringstream>
                                               ( kstrContent
                                               , std::ios::in|std::ios::binary);
    return UploadPart(iPartNumber, piosContent, ui64ContentLength, rError);
}

示例中,存在损耗性能的方面:

  • 构建 std::string const kstrContent
    将裸数据构建 std::string 动态分配内存空间。

  • 构建 std::stringstream 对象
    std::string 构建 std::stringstream 将导致 std::string_buf 通过 std::allocator 再次动态分配内存。

  • 智能指针的引用管理
    对于一个大的文件循环上传分片,由 std::shared_ptr 不断的引用管理,存在一定的计算。

可见,一块内存数据被反复折腾,而不是以较少代价的方式被处理。

@huiguangjun
Copy link
Collaborator

huiguangjun commented May 6, 2019

你可以继承 streambuf, 定义自己的buffer类(例如MyCharBuffer),实现相关的接口,对pkbyContent进行封装。
MyCharBuffer charBuffer(pkbyContent, ui64ContentLength);
std::shared_ptr < std::iostream > charContent = std::make_shared < std::iostream > (&charBuffer);

@huiguangjun
Copy link
Collaborator

为了简化,继承std::stringbuf 作为例子。
class MyCharBuffer : public std::stringbuf
{
public:
MyCharBuffer(char *ptr, std::streamsize size) :
std::stringbuf(std::ios_base::in)
{
_Mysb::setg(ptr, ptr, ptr + size);
_Mysb::setp(ptr + size, ptr + size, ptr + size);
}
};

@ayumukid
Copy link

class MyCharBuffer : public std::stringbuf
{
public:
MyCharBuffer(char *ptr, std::streamsize size) :
std::stringbuf(std::ios_base::in)
{
_Mysb::setg(ptr, ptr, ptr + size);
_Mysb::setp(ptr + size, ptr + size, ptr + size);
}
};
在linux 环境下编译不过

MyOssBuffer.h:12:3: 错误:‘_Mysb’未声明
_Mysb::setp(ptr + size, ptr + size, ptr + size);

@ayumukid
Copy link

MyOssBuffer(char *ptr, std::streamsize size):
	std::stringbuf(std::ios_base::in)
{

#ifdef _WIN32
basic_streambuf::setg(ptr, ptr, ptr + size);
basic_streambuf::setp(ptr + size, ptr + size, ptr + size);
#else
basic_streambuf::setg(ptr, ptr, ptr + size);
basic_streambuf::setp(ptr + size, ptr + size);
#endif

}

使用这种方式 win linux下可以编译通过

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants