【问题标题】:large difference in execution speed during file read文件读取期间的执行速度差异很大
【发布时间】:2013-07-10 15:51:17
【问题描述】:

谁能解释为什么会这样?文件大小最大为 2MB。代码执行时间不到 2 秒。

try {
    while ((line = br.readLine()) != null) {
        System.out.println(line);
}
catch(Exception e)
{           
}

但是当我将代码更改为:

String temp = "";
try {
    while ((line = br.readLine()) != null) {
        temp =temp + line;
}
catch(Exception e)
{
}

我知道它会花费相对更多的时间,但它需要 470 秒的大量时间。为什么会有这种差异?

【问题讨论】:

  • 字符串连接很慢。
  • StringBuilder 可能是这里的一个选项!
  • 您正在将 O(N) 算法更改为 O(N^2) 算法,那么为什么它不会对较大的文件产生很大影响。
  • 每次进行+ 连接时,都会创建一个新的字符串对象。即使对象创建本身并不算太糟糕,您也会留下大量必须经常收集的垃圾。这种情况通常是导致 GC 行为不佳的主要原因。

标签: java file


【解决方案1】:
temp =temp + line;

按原样连接字符串。连接需要创建一个新的字符串对象,并且可能需要进行实习,这需要花费大量时间。相反,请考虑在大多数情况下使用 StringBuilder 或在需要同步的情况下使用 StringBuffer。

创建一次

StringBuilder sb=new StringBuilder()

并附加:

sb.append(line);

然后您可以使用sb.toString() 获取数据。

【讨论】:

  • 在大多数情况下,首选StringBuilder 而不是StringBuffer
  • @hexafraction Yes
  • 是的,StringBuffer 是同步的,而 StringBuilder 不是。
  • 您可以在“新建”缓冲区时初始化缓冲区的大小。如果您可以使用文件大小来估计字符数,那将很方便。 (因为换行符正在消失。)
  • @LeeMeador 这会带来切实的性能优势吗?似乎开销会更少,但我不确定。
【解决方案2】:

在 Java 中,字符串是不可变的。所以这个说法:

temp =temp + line;

为文件中的每一行创建一个新的字符串对象,这会减慢速度。一些更好的选择包括StringBuilderStringBuffer

您可以找到一些基准 here 来比较这 3 种连接字符串方式的速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 2019-09-25
    相关资源
    最近更新 更多