写指针内容而不复制

时间:2018-07-18 09:10:13

标签: c++ performance pointers

我正在尝试打印由指针指向的N个字符,没有终止字符。可以说我有这样的东西(希望我的ascii艺术品在这里还可以。我想将chars / string“ bcd”写入file / stdout)

char* ptr ----> 'a' , 'b' , 'c' , 'd' , 'e' , 'f'

                    ^           ^      
                    |           |
                  begin        end

现在我在那里没有终止符。我有一个指向要写入stdout的字符的开头和结尾的指针(或说一个日志文件)。性能真的很重要,我想避免复制构造std :: string的开销(使用begin / end指针)。

最快的 方法是什么,有人可以告诉我吗?我在Google周围搜索,但什么也看不到。我可以遍历begin-> end并一次打印/写入每个字符,但我想更快地/准备就绪。这是一个理论上的问题(出于我自己的利益),但我想知道在高性能应用程序中是如何做到的(想想低延迟应用程序中的FIX消息字符串)。

非常感谢

格雷厄姆

2 个答案:

答案 0 :(得分:0)

如果您想进行自定义缓冲,我可以建议像这样的东西

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

问题会改善性能吗?我不确定,它甚至会使您的表现恶化。为什么?根据您的机器,coutfstream通常已经以可能合适的大小进行了缓冲。这意味着在被发送到OS对象(文件,管道等)之前,C ++ std实现可能会缓冲它(尽管标准不要求)。可能不需要添加新的缓冲层并提高性能(首先将其复制到缓冲区,然后再将其复制到std缓冲区)。其次,OS对象文件,管道已经映射到内存,即已缓冲。但是,使用这种语言缓冲,您可以实现较少的系统调用,而这可能很昂贵。为了确定您自己的缓冲是否有帮助,应该对它进行基准测试。您没有时间这样做,我建议您将它放到您的范围之外,而不要依赖std和OS,这些通常在此方面是相当不错的。

答案 1 :(得分:0)

您可以使用std::basic_ostream::write

android:background="@drawable/file_name_without_extension"