我的逻辑在这里有什么问题?

时间:2010-04-13 18:12:11

标签: performance logic

在java中,他们说不要连接字符串,而是应该创建一个字符串缓冲区并继续添加它,然后当你完成所有操作时,使用toString()从中获取一个String对象。 这是我没有得到的。他们说出于性能原因这样做,因为连接字符串会产生大量临时对象。但如果目标是性能,那么你就会使用像C / C ++或汇编这样的语言。

使用java的论点是,购买速度更快的处理器要比支付高级程序员编写快速高效的代码便宜得多。 所以一方面,你应该让硬件处理效率低下的问题,但另一方面,你应该使用字符串缓冲来提高java的效率。

虽然我看到你可以做到这两点,但是使用java和stringbuffers,我的问题是你使用更快的芯片或者花更多时间编写更高效的软件的逻辑缺陷在哪里。

7 个答案:

答案 0 :(得分:5)

开发人员应该了解他们的编码选择的含义

编写导致非线性性能的算法 - 多项式,指数或更差,并不是非常困难。如果您在某种程度上不理解语言,编译器和库如何支持您的算法,您可能陷入陷阱,没有多少处理能力会让您厌倦。运行时或内存使用率呈指数级的算法可能会超出任何硬件在合理时间内执行的能力。

假设硬件可以扩展到设计糟糕的算法/编码选择是个坏主意。以一个将100,000个小字符串连接在一起的循环(比如XML消息)为例。这不是一种罕见的情况 - 但是当使用单个字符串连接(而不是StringBuffer)实现时,这将导致99,999个垃圾收集器必须处理的大小增加的中间字符串。如果没有足够的内存,这很容易使操作失败 - 或者最好只是永远运行。

现在在上面的例子中,一些Java编译器通常(但不总是)重写代码以在幕后使用StringBuffer - 但这是例外,而不是规则。在许多情况下,编译器根本无法推断开发人员的意图 - 并且开发人员负责编写有效的代码。

最后一条评论 - 编写高效代码并不意味着花费所有时间来寻找微优化。 过早优化是编写优秀代码的敌人。但是,您不应该将过早优化与在时间/存储方面理解算法的O()性能以及在哪种情况下使用哪种算法或设计做出正确选择相混淆。

作为一名开发人员,你不能忽视这一级别的知识,只是假设你总是可以投入更多的硬件。

答案 1 :(得分:4)

你应该使用StringBuffer而不是连接的论点是一个古老的java货物崇拜神话。 Java编译器本身会将一系列连接转换为单个StringBuffer调用,这使得源代码中完全不需要这种“优化”。

话虽如此,即使您使用的是“慢速”字节码或解释语言,也有合理的理由进行优化。您不希望处理C / C ++的错误,不稳定性和更长的开发周期,因此您使用的语言具有更丰富的功能。 (内置字符串,可以!)但与此同时,您希望代码使用该语言尽可能快地运行,因此您可以避免使用明显低效的构造。 IOW只是因为你使用java放弃某些速度并不意味着你应该完全忘记性能。

答案 2 :(得分:3)

不同之处在于,使用StringBuffer比连接字符串更难或更耗时。一般原则是,如果能够在不增加开发时间/难度的情况下获得效率,则应该这样做:您的原则仅适用于不可能的情况。

答案 3 :(得分:2)

语言较慢并不是使用速度慢得多的算法的借口(而且Java现在并不那么慢。)

如果我们将1个字符连接到n个字符的字符串,我们需要将n + 1个字符复制到新字符串中。如果我们这样做

string s;
for (int i = 0; i < N; ++ i)
  s = s + "c";

然后运行时间为O(N 2 )。

相比之下,字符串缓冲区维护一个可变缓冲区,将运行时间缩短为O(N)。

您不能将CPU加倍以将二次算法简化为线性算法。

(虽然优化器可能已经隐式为你创建了一个StringBuffer。)

答案 4 :(得分:1)

Java!=无效的代码。

您不会购买速度更快的处理器以避免编写高效的代码。一个坏的程序员会编写错误的代码而不管语言。 C / C ++比Java更有效的论点是一个古老的论点,不再重要了。

答案 5 :(得分:1)

在现实世界中,编程语言,操作系统和开发工具并非由真正处理它的人选择。

A公司的一些推销员与你的老板共进午餐,以便出售其操作系统......然后其他一些推销员邀请你的老板在脱衣舞娘那里出售其数据库引擎......等等。

然后,只有这样,他们才聘请了一大批程序员将所有这些结合在一起。他们希望它好看,快速和便宜。

这就是为什么你最终可能会在移动设备上使用Java编写高端性能应用程序,或者在使用Python的Windows上编写漂亮的3D图形...

所以,你的权利,但没关系。 :)

答案 6 :(得分:0)

您应该始终将优化放在尽可能的位置。你不应该只是因为你有一个快速的处理器而“懒惰编码”......

我真的不知道stringbuffer是如何工作的,也不是我使用Java,但假设java将字符串定义为char [],那么在执行str1 + str2 + str3 + str4时你会分配大量的虚拟字符串+ str5,你真的只需要创建一个长度为str1.length + ... str5.length的字符串并复制一切ONCE ...

但是,智能编译器会优化并自动使用stringbuffer