当前位置: 首页 > 知识库问答 >
问题:

弦连接真的那么慢吗?

戚阳文
2023-03-14

我目前正在研究字符串concat选项,以及它们对整体性能的影响。我的测试用例产生了让我震惊的结果,我不确定我是否忽略了什么。

这里是交易:在java中执行“something”“somethingElse”将(在编译时)创建一个新的StringBuilder

对于我的测试用例,我正在从我的硬盘加载一个文件,其中包含1661行示例数据(经典的“Lorem Ipsum”)。这个问题不是关于I/O性能,而是关于不同字符串concat方法的性能。

public class InefficientStringConcat {

    public static void main(String[] agrs) throws Exception{
        // Get a file with example data:

        System.out.println("Starting benchmark");
        // Read an measure:
        for (int i = 0; i < 10; i++){
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(new FileInputStream(new File("data.txt")))
            );

            long start = System.currentTimeMillis();
            // Un-comment method to test:
            //inefficientRead(in);
            //betterRead(in);
            long end = System.currentTimeMillis();
            System.out.println("Took "+(end-start)+"ms");

            in.close();
        }



    }

    public static String betterRead(BufferedReader in) throws IOException{
        StringBuilder b = new StringBuilder();
        String line;
        while ((line = in.readLine()) != null){
            b.append(line);
        }
        return b.toString();
    }

    public static String inefficientRead(BufferedReader in) throws IOException {
        String everything = "", line;
        while ((line = in.readLine()) != null){
            everything += line;
        }
        return everything;
    }
}

如您所见,两个测试的设置是相同的。以下是结果:

使用无效阅读()-方法:

Starting benchmark
#1 Took 658ms
#2 Took 590ms
#3 Took 569ms
#4 Took 567ms
#5 Took 562ms
#6 Took 570ms
#7 Took 563ms
#8 Took 568ms
#9 Took 560ms
#10 Took 568ms

使用betterRead()-方法

Starting benchmark
#1 Took 42ms
#2 Took 10ms
#3 Took 5ms
#4 Took 7ms
#5 Took 16ms
#6 Took 3ms
#7 Took 4ms
#8 Took 5ms
#9 Took 5ms
#10 Took 13ms

我在运行测试时,对java-命令没有额外的参数。我从2009年初开始运行MacMini3,1和Sun JDK 7:

[luke@BlackBox ~]$ java -version
java version "1.7.0_09"
Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) Client VM (build 23.5-b02, mixed mode)

我觉得这是一个很大的不同。我在衡量这一点时是做错了什么,还是应该这样?

共有2个答案

上官羽
2023-03-14

这正是应该发生的事情betterRead需要线性时间<代码>低效读取需要二次时间。

徐晔
2023-03-14

我在衡量这一点时是做错了什么,还是应该这样?

这是应该发生的。使用重复的字符串串联构建长字符串是一种已知的性能反模式:每个串联都必须创建一个新字符串,其中包含原始字符串的副本和附加字符串的副本。你最终的表现是O(N2)。当您使用StringBuilder时,大多数时候您只是将额外的字符串复制到缓冲区中。偶尔,缓冲区需要耗尽空间并需要扩展(通过将存量数据复制到新缓冲区),但这种情况不会经常发生(由于缓冲区扩展策略)。

有关详细信息,请参阅我关于字符串串联的文章——这是一篇非常古老的文章,所以早于StringBuilder,但是基本原理没有改变。(基本上StringBuilder就像StringBuffer,但是没有同步。)

 类似资料:
  • 我可以使用内置函数来检查这一点。 我也可以在使用条件时使用这些真实性值。例如: 这不适用于运算符,但: 有人能解释为什么的行为似乎与条件不同吗?

  • 问题内容: 已锁定 。该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。它目前不接受新的答案或互动。 Java 因其速度慢而享有一定的声誉。 Java真的很慢吗? 如果是,为什么?瓶颈在哪里?是因为JVM效率低下吗?垃圾收集?纯字节码库而不是JNI包装的C代码?许多其他语言都具有这些功能,但是它们并没有因速度慢而享有盛誉。 问题答案: 现代Java是最快的语言之一,即使它仍然是内存消耗大的

  • 问题内容: 我在PHP应用程序中使用PDO。它连接到同一服务器上的MySQL服务器: 我创建了两个页面,它们具有相同的输出(只是纯HTML中的一些虚拟数据),其中之一包含创建PDO的调用。如果我打开不使用连接的页面,则响应速度将加快0.5到1秒。 问题答案: 我一直在进行一些谷歌搜索,在阅读了此主题之后,我更改为。那解决了问题。

  • 问题内容: 我使用JDBC连接到MySQL。在时,一切正常。 但是,当我将应用程序移动到Intranet中的另一台计算机上并用于连接到MySQL数据库时,大约需要1分钟才能成功连接到MySQL。这是怎么回事? 问题答案: 好吧,这可能是DNS问题。您可以通过从配置文件中的选项开始禁用DNS主机名查找。 在这里阅读更多详细信息:http : //dev.mysql.com/doc/refman/5.

  • translated_page: https://github.com/PX4/Devguide/blob/master/en/simulation/ros_interface.md translated_sha: 95b39d747851dd01c1fe5d36b24e59ec865e323e ROS仿真接口 模拟自驾仪会在端口14557开放第二个MAVLink接口。将MAVROS连接到这个端口

  • 我最近学习了PDO和学说2.2.2来构建一个应用程序。但是我将在我的环境中处理一些关键的约束(大量的数据,连接速度...等等)我知道学说有一个PDO层,所以也许PDO更快,但是我想要使用像Hibernate这样的真实ORM框架。 在阅读了这篇文章后,PDO与条令 我必须知道条令是否比PDO慢。 谢谢你