Readline 太慢 - 更快吗?

Posted

技术标签:

【中文标题】Readline 太慢 - 更快吗?【英文标题】:Readline is too slow - Anything Faster? 【发布时间】:2011-12-07 01:42:15 【问题描述】:

我正在使用 BufferedReader 和 InputStreamReader 从流中读取数据,以创建一个从读取器创建的长字符串。它达到超过 100,000 行,然后抛出 500 错误(服务器上的调用失败)。我不确定是什么问题,有什么比这种方法更快的方法吗?当行数为数千但我正在处理大型数据集时,它可以工作。

BufferedReader in = new BufferedReader(new InputStreamReader(newConnect.getInputStream()));
String inputLine;               
String xmlObject = "";
StringBuffer str = new StringBuffer();

while ((inputLine = in.readLine()) != null) 
    str.append(inputLine);
    str.toString();
       
in.close();

提前致谢

【问题讨论】:

如果您正在将其读入 RAM 内存,那么您可能内存不足 - 这导致了异常 (?) 另外,您能否提供更多信息,说明您为什么要创建“一个长字符串” - 不是说你不应该,而是请赐教。 插座的另一边是什么?听起来服务器进程有某种超时。 我在服务器端执行此操作,我正在创建一个从 servlet 中提取 xml 数据的 GWT 应用程序。我有一个长的 XML 文件,需要读入并创建成一个长字符串来解析 @user971337 - 您是否尝试过增加 BufferedReader 的缓冲区大小? 最后一次调用 (str.toString()) 很可能是导致性能下降的原因,因为它需要复制整个 StringBuffer。您在循环中调用它,因此如果文件中有 100.000 行,您最终会得到 100.000 个 StringBuffer 副本。而且您甚至不使用 toString() 的结果,那为什么会出现呢?其他优化提示:用你正在读取的文件的大小初始化你的 StringBuffer。 【参考方案1】:

readline() 可以以大约 90 MB/s 的速度读取,这是您对数据读取速度缓慢所做的事情。顺便说一句,readline 删除了换行符,因此您使用的这种方法存在缺陷,因为它会将所有内容都变成一行。

与其重新发明***,我建议你试试FileUtils.readLineToString() 这将有效地将文件作为字符串读取而不会丢弃换行符。

【讨论】:

哇,我刚刚取出了两行代码,它飞了!!!我只需要将所有这些保存到一个字符串中,这就是 XML 解析器从长字符串中读取数据的方式。除了 FileUtils.readLineToString 之外还有什么建议吗?或者你认为这会解决它? 如果它要求您将输入作为字符串提供,我无法想象您使用的是什么 XML 解析器。我所知道的每个 XML 解析器都会接受作为 File、InputStream 或 Reader 的输入。 @user971337 JDK 附带的 XML 解析器都接受 InputStreams, Readers, Files, URLs, ...或者如果你做了它自己修复它。读取整个输入,然后构造一个字符串,然后将其传递给解析器会引入完全不必要的延迟和内存成本。只需将解析器连接到流。 使用 FileUtils 的好建议。【参考方案2】:

创建一个从读者那里获得的长字符串。

您是否有机会这样做来创建您的“长字符串”?

String string;
while(...) 
 string+=whateverComesFromTheSocket;

如果是,则将其更改为

StringBuilder str = new StringBuilder(); //Edit:Just changed StringBuffer to StringBuilder
while(...)
 str.append(whateverComesFromTheSocket);
String string = str.toString(); 

String 对象是不可变的,当您执行 str+="something" 时,内存被重新分配,str+"something" 被复制到新分配的区域。这是一项代价高昂的操作,运行 51,000 次是一件极其糟糕的事情。

StringBuffer 和 StringBuilder 是 String 的可变兄弟,StringBuilder,非并发比 StringBuffer 更高效。

【讨论】:

BufferedReader in = new BufferedReader(new InputStreamReader(newConnect.getInputStream()));字符串输入线;字符串 xmlObject = "";整数计数 = 0; StringBuffer str = new StringBuffer(); while ((inputLine = in.readLine()) != null) System.out.println(count);计数++; str.append(inputLine); xmlObject = str.toString(); 过早的 EOF 是我仍然得到的 为什么 xmlObject = str.toString();在循环内部? 应该在那里,但它仍然很慢,我认为阅读 50,000 行不应该超过 25 秒。必须有一种方法可以更快地读取它,尤其是从服务器端

以上是关于Readline 太慢 - 更快吗?的主要内容,如果未能解决你的问题,请参考以下文章

重载 Console.ReadLine 可能吗? (或任何静态类方法)

18. IO会阻塞吗?readLine是不是阻塞的?

提高 pyserial readline 速度

qpython 没有“gnu-readline”功能

文件操作之增删改查

c# 为啥读取Txt文件太慢?