【发布时间】:2015-07-22 11:19:52
【问题描述】:
我似乎遇到了 InputStream 和扫描仪的奇怪性能问题。
我在一个日志文件上使用tail -F,本质上是将它实时流式传输到我的代码中。当我这样做时,我在 60 秒内得到大约 7,500,000 行(每秒 125,000 行)。很公平。
现在,由于日志文件的写入速度实际上超过 125,000 行/秒,因此我对日志文件进行 grep 以缩小结果范围。
当我在我的 linux shell 中运行更新后的tail -F 命令时,我在 60 秒内获得了大约 40,000 行(667 行/秒)。远低于我在 60 秒内的 141,000 行,当它没有被清除时。
但是,当我通过我的代码运行完全相同的命令时,我在 60 秒内得到 16,000 行(266 行/秒)!所以在某处我失去了一半的台词,我挠头想知道为什么。
代码:
public Boolean call() {
//send command with no wait.
final PrintStream out = new PrintStream(eCli.getOutputStream());
//Notice the command terminator "\n" which is needed here for the command to be executed.
out.print(tailCommandBuilder(logDir,fileName, filters));
out.print((char)4);
out.print('\n');
final Scanner s = new Scanner(eCli.getInputStream());
out.flush();
//InputStream in = new BufferedInputStream(eCli.getInputStream());
StopWatch sw = new StopWatch();
sw.reset();
sw.start();
log.info("Stopwatch started.");
double lineCounter = 0;
//final BufferedReader buffReader = new BufferedReader(new InputStreamReader(in));
try {
LOOP:
while (keepRunning.get()) {
if (s.hasNextLine()) {
String st = s.nextLine();
lineCounter++;
} else {
keepRunning.getAndSet(false);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
log.error("Error in IORead: " + e.getMessage() + e.getStackTrace());
} finally {
sw.stop();
log.info("Total Time: " + sw.getTime());
s.close();
log.warn("Total Lines Read: " + lineCounter);
eCli.clearBuffer();
eCli.disconnect();
}
return true;
}
编辑:
如前所述,eCli 是“扩展 Cli”类的一个实例,它实现了一个命令行接口类型实例。它使用 InputStream/OutputStream 进行通信。
我不将 --line-buffering 与 grep 一起使用。
【问题讨论】:
-
我认为两种情况下的“tail -f”输出(
linux/java)是相同的?eCli是什么? -
你是否在 grep 中使用 --line-buffered 标志?
-
我不使用 --line-buffered。生病调查 eCli 是 CLI 实例的自定义实现。重要的是它使用 InputStream/OutputStream 进行通信
-
如果这些行继续出现“糟糕”的时机,会不会是你的
sleep(1)被执行得更频繁? -
实际上 Hanno,我发现 .hasNextLine() 无论如何都会阻塞(如果没有输入),因此逻辑永远不会受到影响。只是我保留在那里的草率编码实践。
标签: java linux eclipse logging inputstream