C++ 在不复制的情况下写入指针内容

C++ 在不复制的情况下写入指针内容,c++,performance,pointers,C++,Performance,Pointers,我试图打印指针指向的N个字符,没有终止字符。让我们说我有这样的东西(希望我的ascii艺术作品在这里没问题..我想把字符/字符串“bcd”写到file/stdout) 现在我在那里没有终止字符。我有一个指向要写入标准输出的字符的开始和结束的指针(或者一个日志文件)。性能非常重要,比如说,我希望避免复制构造std::string(使用开始/结束指针)的开销 有谁能告诉我,最快的方法是什么?我在谷歌上搜索过,但什么也看不到。我可以迭代开始->结束,一次打印/写入每个字符,但我想做一些更快/准备好的东

我试图打印指针指向的N个字符,没有终止字符。让我们说我有这样的东西(希望我的ascii艺术作品在这里没问题..我想把字符/字符串“bcd”写到file/stdout)

现在我在那里没有终止字符。我有一个指向要写入标准输出的字符的开始和结束的指针(或者一个日志文件)。性能非常重要,比如说,我希望避免复制构造std::string(使用开始/结束指针)的开销

有谁能告诉我,最快的方法是什么?我在谷歌上搜索过,但什么也看不到。我可以迭代开始->结束,一次打印/写入每个字符,但我想做一些更快/准备好的东西。这是一个理论问题(为了我自己的利益),但我想知道在高性能应用程序中如何做到这一点(想想在低延迟应用程序中修复消息字符串)

多谢


格雷厄姆

如果你想定制缓冲,我可以建议你做这样的事情

class buffered_stream_buf : public std::streambuf {
public:
  buffered_stream_buf(std::ostream* stream)
    : _size(), _stream(stream), _out(_stream->rdbuf()) {
    _stream->rdbuf(this);
  }

  ~buffered_stream_buf() {
    _stream->flush();
    _stream->rdbuf(_out);
  }

  int sync() override {
    if (_size) {
      _out->sputn(_buffer, _size);
      _size = 0;
    }
    return _out->pubsync();
  }

  int overflow(int c) override {
    if (c == std::streambuf::traits_type::eof()) {
      return !std::streambuf::traits_type::eof();
    }
    _buffer[_size] = static_cast<char>(c);
    ++_size;
    if (_size == sizeof(_buffer) && sync() != 0)
      return std::streambuf::traits_type::eof();
    return c;
  }

private:
  char _buffer[8 * 1024];
  size_t _size;
  std::ostream* _stream;
  std::streambuf* _out;
};

int main() {
  // Unbuffering `cout` might be a good idea:
  // to avoid double copying
  std::cout.setf(std::ios::unitbuf);

  buffered_stream_buf mycoutbuf(&std::cout);
  std::ofstream f("testmybuffer.txt", std::ios_base::out);
  buffered_stream_buf myfbuf(&f);
  std::cout << "Hello";
  f << "Hello";

  std::string my_long_string("long_long_long");
  auto b = my_long_string.begin() + 3;
  auto e = my_long_string.begin() + 5;
  for (; b != e; ++b) {
    std::cout << *b;
    f << *b;
  }

  return 0;
}
类缓冲\u流\u buf:public std::streambuf{
公众:
缓冲流(std::ostream*流)
:_size(),_stream(stream),_out(_stream->rdbuf()){
_流->rdbuf(此);
}
~buffered_stream_buf(){
_流->刷新();
_流->rdbuf(_out);
}
int sync()重写{
如果(_大小){
_out->sputn(\u缓冲区,\u大小);
_尺寸=0;
}
返回_out->pubsync();
}
int溢出(int c)覆盖{
如果(c==std::streambuf::traits_type::eof()){
return!std::streambuf::traits_type::eof();
}
_缓冲区[\u大小]=静态\u转换(c);
++_大小;
如果(_size==sizeof(_buffer)&&sync()!=0)
返回std::streambuf::traits_type::eof();
返回c;
}
私人:
字符缓冲区[8*1024];
大小(t)大小;;
std::ostream*_流;
标准::streambuf*_out;
};
int main(){
//解除“cout”可能是个好主意:
//避免重复复制
std::cout.setf(std::ios::unitbuf);
缓冲流(mycoutbuf)(&std::cout);
流f的std::of(“testmybuffer.txt”,std::ios_base::out);
缓冲流&buf myfbuf(&f);
std::cout您可以使用:


也可以使用“代替代码> STD::String < /Cord>”,也注意到,无论你的代码有多快,最大的瓶颈是写到控制台上。无论你使用C函数来编写<代码> STDUD> <代码>,或者格式化的C++流输出到 STD::CUT,这将使你自己的影响几乎可以忽略不计。m::write
.Cstdio:
fwrite
。尽管最大的瓶颈始终是实际的写入(在操作系统级别)。我怀疑您需要
end-begin+1
,因为OP的结束指针出于某种原因没有超过结束。
class buffered_stream_buf : public std::streambuf {
public:
  buffered_stream_buf(std::ostream* stream)
    : _size(), _stream(stream), _out(_stream->rdbuf()) {
    _stream->rdbuf(this);
  }

  ~buffered_stream_buf() {
    _stream->flush();
    _stream->rdbuf(_out);
  }

  int sync() override {
    if (_size) {
      _out->sputn(_buffer, _size);
      _size = 0;
    }
    return _out->pubsync();
  }

  int overflow(int c) override {
    if (c == std::streambuf::traits_type::eof()) {
      return !std::streambuf::traits_type::eof();
    }
    _buffer[_size] = static_cast<char>(c);
    ++_size;
    if (_size == sizeof(_buffer) && sync() != 0)
      return std::streambuf::traits_type::eof();
    return c;
  }

private:
  char _buffer[8 * 1024];
  size_t _size;
  std::ostream* _stream;
  std::streambuf* _out;
};

int main() {
  // Unbuffering `cout` might be a good idea:
  // to avoid double copying
  std::cout.setf(std::ios::unitbuf);

  buffered_stream_buf mycoutbuf(&std::cout);
  std::ofstream f("testmybuffer.txt", std::ios_base::out);
  buffered_stream_buf myfbuf(&f);
  std::cout << "Hello";
  f << "Hello";

  std::string my_long_string("long_long_long");
  auto b = my_long_string.begin() + 3;
  auto e = my_long_string.begin() + 5;
  for (; b != e; ++b) {
    std::cout << *b;
    f << *b;
  }

  return 0;
}
std::cout.write(begin, end - begin);