Java 优化输入流读取速度/提高级联速度的方法
目前我正在读取一个1000000+/-行输入(示例:),它以一个“;”结尾 使用此代码在我的电脑上阅读需要超过20秒(太长了): 使用计时方法,我得到了奇怪的结果:Java 优化输入流读取速度/提高级联速度的方法,java,optimization,io,inputstream,string-concatenation,Java,Optimization,Io,Inputstream,String Concatenation,目前我正在读取一个1000000+/-行输入(示例:),它以一个“;”结尾 使用此代码在我的电脑上阅读需要超过20秒(太长了): 使用计时方法,我得到了奇怪的结果: long start = System.nanoTime(); pol = readFromStandardIO(); long elaspedTime = System.nanoTime() - start; System.out.println("reading stream took: " + elaspedTime);
long start = System.nanoTime();
pol = readFromStandardIO();
long elaspedTime = System.nanoTime() - start;
System.out.println("reading stream took: " + elaspedTime);
它输出:
reading stream took: 1914854722
行连接似乎在减慢速度:
returnValue = returnValue.concat(userInput)
没有它,一切都是瞬间的
如何提高连接的速度
public static String readFromStandardIO() {
StringBuilder returnValue = new StringBuilder(9999999);
try {
BufferedReader reader = new BufferedReader(System.in);
String userInput;
while ((userInput = reader.readLine()) != null) {
returnValue.append(userInput);
}
reader.close();
} catch (Exception e) {
}
return returnValue.toString();
}
或者这个更快(如果您的jdk支持*.nio):
字符串连接不是免费的:问题是内存分配 每次延长字符串时,字符串缓冲区都需要放大,这意味着1)动态分配新内存区域,2)移动整个字符串 假设您将字符串分成100个字符的块,并执行1000次。您将调用分配器100次,并移动100+200+300+。。。100000个字符,即50050000而不是100000 更一般地说,在N次读取中获取字符串意味着每个字符移动大约N/2次,而不是。。。一,
解决方法是预先分配一个足够大的缓冲区,然后“手动”执行串联操作。
系统。currentTimeMillis()
以毫秒为单位,开始
以纳秒为单位。对不起,我的错你是对的,我只是在尝试不同的方法。读取流花费了:14094164770,这仍然是14秒…从循环中删除所有代码,除了readLine,以查找其IO问题或您的解析代码是否变慢。因此,“returnValue=returnValue.concat(userInput)”行使所有内容变慢…这需要6秒(这更好!);但有没有办法让它更快呢?如果您使用的是第二个变量,那么尝试在字节缓冲区中分配更多内存,如果第二个变量有红色1000000行文件6毫秒,而第一个变量需要224毫秒
public static String readFromStandardIO() {
StringBuilder returnValue = new StringBuilder(9999999);
try {
BufferedReader reader = new BufferedReader(System.in);
String userInput;
while ((userInput = reader.readLine()) != null) {
returnValue.append(userInput);
}
reader.close();
} catch (Exception e) {
}
return returnValue.toString();
}
public static String readFromStandardNIO() {
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(20480000);
try {
ReadableByteChannel channel = Channels.newChannel(System.in);
channel.read(buffer);
channel.close();
} catch (Exception e) {
}
return new String(buffer.array());
}