告诉"endl"不要刷新
Tell `endl` not to flush
我的程序将大量短行打印到cout
。
作为一个略显做作的例子,我的行看起来有点像:
cout<<"The variable's value is: "<<variable<<endl;
我希望程序能快速运行,而且我确实相信endl
正在杀死我,因为每次使用它时,它都会在cout
上启动缓冲区刷新。
现在,互联网上的一些人说我可以这样做:
cout<<"The variable's value is: "<<variable<<"n";
但这似乎不是一个好的解决方案,因为endl
抽象了可能指定终点线的特定系统特定方式,而n
没有。这似乎也是一个糟糕的解决方案,因为如果我将来需要缓冲,我将不得不修改整个代码库。
因此,我想问,有没有办法禁用endl
的缓冲区刷新方面?
编辑
进一步挖掘似乎表明endl
和n
都尊重操作系统可能选择的结束其行的各种方式。输出流似乎还检测到它是否处于潜在的交互状态,并相应地进行缓冲和刷新。因此:这个问题可以通过手动告诉输出流执行主动缓冲来解决。。。如果我能想办法的话。
endl抽象了特定于系统的方式,可以指定结束行,其中as \n没有"。
std::endl
被定义为输出'n'
,然后进行刷新。系统特定的换行符的正确抽象就是'n'
。
为了防止刷新,不使用std::endl
。此外,如果标准输出连接到或可能连接到交互式设备,则可以对其进行行缓冲,在这种情况下,换行符将刷新流。如果有问题,请使用连接到命名文件的ofstream
。我认为在类Unix系统上,只有当标准输出是终端时,才会发生行缓冲。
endl
刷新。如果你不想要这种行为,就不要使用endl
。如果你想轻松地更改代码,可以使用自己的操纵器:
inline std::ostream& myendl( std::ostream& os ){
os.put(os.widen('n'));
return os;
}
这样,您就可以在一个地方轻松地更改myendl
的行为。
根据http://en.cppreference.com/w/cpp/io/manip/endl
endl::在输出序列os中插入一个换行符,并通过调用os.put(os.widen('n'))
和os.flush()
对其进行刷新。
因此,您似乎只想编写os.put(os.widen('n'))
,从这个定义来看,它应该是安全、可移植和正确的,并满足您的主要需求。
有一个std::nounitbuf,它被证明在这件事上有一些影响。然而,我没有注意到任何区别。为了绕过ostream关于何时或何时不冲洗的所有想法,我尝试了这个:
std::ostringstream oss;
// std::cout << std::nounitbuf;
for( int i = 0; i < 1000000; i++ ){
// std::cout << "Test " << "file" << 'n';
oss << "Test " << "file" << 'n';
}
std::cout << oss.str();
这将执行时间从约33秒提高到约25秒。
如果你的输出到xterm,你的执行速度会受到xterm滚动等工作的严重限制。如果你使用管道过滤掉不必要的行,你会看到速度的显著提高,例如
./program | grep -v "The variable"
如果刷新是个问题,您可以实现一个流缓冲区,该缓冲区覆盖sync()
成员函数,以便在指定的情况下只刷新到外部设备。如果您打算在整个程序中更改这些首选项,它还必须创建自己的操纵器flush_on_endl
和noflush_on_endl
。
#include <iostream>
static int disable() {
static int index(std::ios_base::xalloc());
return index;
}
class save_buffer
{
public:
save_buffer(std::ios& other)
: str(other), buf(other.rdbuf())
{ }
~save_buffer() { str.rdbuf(buf); }
private:
std::ios& str;
std::streambuf* buf;
};
class syncing_buffer_optional : public std::streambuf, private save_buffer
{
public:
syncing_buffer_optional(std::ostream& other)
: save_buffer(other),
buf(other.rdbuf()),
disable_sync(other.iword(disable()))
{ }
std::streambuf::int_type overflow(std::streambuf::int_type c)
{
buf->sputc(c);
return 0;
}
int sync()
{
return disable_sync? 0: buf->pubsync();
}
private:
std::streambuf* buf;
bool disable_sync;
};
std::ostream& flush_on_endl(std::ostream& os)
{
os.iword(disable()) = false;
return os;
}
std::ostream& noflush_on_endl(std::ostream& os)
{
os.iword(disable()) = true;
return os;
}
std::ostream& endl(std::ostream& os)
{
syncing_buffer_optional eb(os);
os.rdbuf(&eb);
return os << std::endl;
}
int main()
{
std::cout << noflush_on_endl << endl;
}
- 是否可以配置提升日志刷新?
- 如何在qt中同步应用程序和显示器的刷新率?
- 在 3ds Max 中更新进度条后,环境和效果 UI 不刷新
- std::endl,在 Python 中是否有等价物?(返回 + 刷新)
- 在 directx11 代码中更改全屏模式下的刷新率不起作用
- 如何在 Windows 中立即刷新文件夹图标
- 'char (*RtlpNumberOf(T (&)[N]))[N]':无法从"char *"
- Arduino IDE 错误 - 无法找到数字文字运算符"运算符""f900ff"
- 刷新来自Qpid质子连接的所有消息而不是等待?
- 如何让 cout 缓冲区在 ubuntu 上刷新
- "inline"、"constexpr"或"noexcept"
- "非静态数据成员之前需要构造函数" - 我是否使用"boost::variant"
- 我必须安装"libbitcoin-server"才能包含"bitcoin.hpp"
- 显示DHT1306温度数据时如何正确刷新Adafruit 11 OLED?
- 为什么PNG图像的stdout有时会在printf中刷新图像的一半
- QML:收到C 信号从C 传递时刷新问题
- 托管语言是否锁定本机库的刷新和重新加载变量?
- 记录器何时应刷新
- 在 Linux 上编译一个 c++ 应用程序,并在 TI TIVA TM4C123GH6PM上刷新它
- 如何刷新CPU缓存中的地址范围?