考虑竞争性编程的情况,我必须从控制台读取2 * 10 ^ 5(甚至更多)数字。然后,我使用BufferedReader
甚至为了提高性能而使用了DataInputStream
在后台使用的自定义阅读器类。
快速的互联网搜索给了我这个。
我们可以使用
java.io
较小的数据流,也可以使用较大的流java.nio
。
所以我想尝试java.nio
控制台输入并针对java.io
性能进行测试。
java.nio
?System.in
使用java.nio
?任何相关信息将不胜感激。
谢谢✌️
您可以打开一个标准输入
FileInputStream stdin = new FileInputStream(FileDescriptor.in);
FileChannel stdinChannel = stdin.getChannel();
将stdin重定向到文件后,可能会执行诸如查询大小,执行向其他通道的快速传输甚至内存映射之类的操作。但是,当输入是真实的控制台或管道,或者您正在读取字符数据时,性能不太可能出现显着差异。
性能取决于您阅读的方式,而不是所使用的类。
直接在通道上操作以处理空格分隔的十进制数字的代码示例是
CharsetDecoder cs = Charset.defaultCharset().newDecoder();
ByteBuffer bb = ByteBuffer.allocate(1024);
CharBuffer cb = CharBuffer.allocate(1024);
while(stdinChannel.read(bb) >= 0) {
bb.flip();
cs.decode(bb, cb, false);
bb.compact();
cb.flip();
extractDoubles(cb);
cb.compact();
}
bb.flip();
cs.decode(bb, cb, true);
if(cb.position() > 0) {
cb.flip();
extractDoubles(cb);
}
private static void extractDoubles(CharBuffer cb) {
doubles: for(int p = cb.position(); p < cb.limit(); ) {
while(p < cb.limit() && Character.isWhitespace(cb.get(p))) p++;
cb.position(p);
if(cb.hasRemaining()) {
for(; p < cb.limit(); p++) {
if(Character.isWhitespace(cb.get(p))) {
int oldLimit = cb.limit();
double d = Double.parseDouble(cb.limit(p).toString());
cb.limit(oldLimit);
processDouble(d);
continue doubles;
}
}
}
}
}
这比使用更复杂java.util.Scanner
或一个BufferedReader
的readLine()
后面split("\\s")
,但具有避免正则表达式引擎的复杂度的优点,以及不产生String
对于线对象。如果每行或空行有多个数字,即行字符串与数字字符串不匹配,则可以节省字符串构造所固有的复制开销。
此代码仍在处理任意字符集。当您知道期望的字符集并且它是基于ASCII的时,使用轻量级转换而不是,如此答案CharsetDecoder
所示,可以提高性能。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句