请看以下四个程序。在 Windows 下使用 Freepascal 构建它们并运行,将输出重定向到任何文件,并注意它所花费的时间。
我的结果是:所有程序的运行时间大致相同(大约 6 秒),尽管第四个程序的输出字节数是原来的 100 倍。这意味着第四个程序每字节输出的运行速度比其他树快得多。
对于第二个程序,缓慢的原因很明显:flush
调用。对于第三个程序,原因不是很明显,但可以合理地假设每次调用 writeln
到 stdout 都会隐式刷新输出缓冲区。
然而,目前还不清楚为什么第一个程序比第四个程序慢那么多。然而,添加 flush(output);
(见程序 2)并没有太大改变时间的事实似乎意味着即使在每次 write
之后 FPC 也会刷新输出缓冲区,这将解释所有的行为。只有当输出到标准输出,甚至重定向时,才会发生这种情况;如果我使用分配/重写显式输出到特定文件,那么不带刷新的程序运行速度比带刷新的程序快得多——正如预期的那样。
在 Linux 下,运行时间分别为 0.01 秒、0.65 秒、0.01 秒、0.30 秒(输出大 100 倍)。这里很明显 flush() 会减慢程序速度,因此在 Linux FPC 下似乎不会每次都刷新标准输出。
我尝试用谷歌搜索 FPC 是否真的在每个输出上刷新标准输出缓冲区(无论是 write
还是 writeln
),但除了示例中的注释外没有找到任何信息来自 flush 函数文档的程序,位于 http://www.freepascal.org/docs-html/rtl/system/flush.html , 评论提到 writeln
到 'output' 总是导致刷新 [而不是 write
]。但是,那里的示例在 Windows 和 Linux 下都不会产生预期的输出。事实上,在 Windows 下,无论是否重定向,在每次写入和写入后,输出似乎都会被刷新,而在 Linux 下,当输出未被重定向时也是如此。在具有重定向输出的 Linux 下,似乎根本没有隐式刷新。
所以,我的问题是:
- 在 Windows 上,无论输出是否重定向到文件,FPC 是否在每次输出后刷新输出缓冲区,无论是
write
还是writeln
?< - 如果是,那么有什么方法可以关闭它(一些编译器指令,或解决方法)?我仍然需要将输出保存到 stdout,这样如果我在没有任何重定向的情况下启动程序,它就会将文本输出到控制台。 (我知道由于缓冲,我可能会看到它在奇怪的时间出现,这不是问题。)
- 如果不是,那么为什么第一个程序比第四个运行得慢得多?
我的系统是 Windows XP,在 Kubuntu 14.04 下的 VirtualBox 下带有 FPC 2.6.4,而 Kubuntu 14.04 本身带有 FPC 2.6.2。我没有机会尝试在真正的 Windows 机器上运行它,但我有理由相信那里的情况是一样的。
程序:
var i,j:integer;
s:string;
begin
for j:=1 to 1000 do begin
for i:=1 to 10 do
write('!');
end;
end.
var i,j:integer;
s:string;
begin
for j:=1 to 1000 do begin
for i:=1 to 10 do begin
write('!');
flush(output);
end;
end;
end.
var i,j:integer;
s:string;
begin
for j:=1 to 1000 do begin
for i:=1 to 10 do
writeln('!');
end;
end.
var i,j:integer;
s:string;
begin
for j:=1 to 10000 do begin
s:='';
for i:=1 to 100 do
s:=s+'!';
write(s);
end;
end.
最佳答案
要防止刷新 Stdout,请将以下代码片段插入您的程序中:
// Textrec is defined in sysutils
uses
sysutils;
// ...
// disabled flushing after each write(ln) on Output, do this at the start of the program
Textrec(Output).FlushFunc:=nil;
但请注意,这意味着写入可能不会在程序结束前完成。
您甚至可以通过增加 stdout 的输出缓冲区来进一步加速程序:
// define buffer
var
buf : array[1..100000] of byte;
// ...
// install buffer, do this at the start of the program
SetTextBuf(Output,buf,sizeof(buf));
关于windows - Freepascal 刷新 Windows 下每个输出的标准输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26948884/