考虑竞争性编程的场景,我必须从控制台读取2*10^5 (甚至更多)数字。然后,我使用BufferedReader,甚至为了更快的性能,我使用自定义读取器类,它在幕后使用DataInputStream。
快速互联网搜索给了我这个。
我们可以使用
java.io来处理更小的数据流,而对于大型流,我们可以使用java.nio。
因此,我想尝试java.nio控制台输入,并根据java.io性能测试它。
java.nio读取控制台输入吗?java.nio从System.in读取数据吗?H 219G 220如有任何相关资料,将不胜感激。
谢谢✌️
发布于 2020-05-28 07:45:38
您可以打开一个像stdin这样的通道
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")更复杂,但它的优点是避免了regex引擎的复杂性,并且不为行创建String对象。如果每行有多个数字或空行,即行字符串与数字字符串不匹配,则可以节省字符串构造固有的复制开销。
此代码仍在处理任意字符集。当您知道预期的字符集并基于ASCII时,使用轻量级转换而不是CharsetDecoder (如this answer中所示)可以获得额外的性能提升。
https://stackoverflow.com/questions/62058966
复制相似问题