我的逻辑有什么问题吗?
在java中,他们说不要连接字符串,相反,你应该创建一个字符串缓冲区并不断添加它,然后当你完成后,使用toString()从中获取一个String对象。 这是我不明白的。他们说这样做是出于性能原因,因为连接字符串会产生大量临时对象。但如果目标是性能,那么您会使用 C/C++ 或汇编语言。
使用java的理由是,购买更快的处理器比花钱请高级程序员编写快速高效的代码要便宜得多。 因此,一方面,您应该让硬件解决效率低下的问题,但另一方面,您应该使用字符串缓冲区来提高 java 的效率。
虽然我看到你可以同时使用 java 和 stringbuffers,但我的问题是,你要么使用更快的芯片,要么花费额外的时间编写更高效的软件,逻辑上的缺陷在哪里。
In java they say don't concatenate Strings, instead you should make a stringbuffer and keep adding to that and then when you're all done, use toString() to get a String object out of it.
Here's what I don't get. They say do this for performance reasons, because concatenating strings makes lots of temporary objects. But if the goal was performance, then you'd use a language like C/C++ or assembly.
The argument for using java is that it is a lot cheaper to buy a faster processor than it is to pay a senior programmer to write fast efficient code.
So on the one hand, you're supposed let the hardware take care of the inefficiencies, but on the other hand, you're supposed to use stringbuffers to make java more efficient.
While I see that you can do both, use java and stringbuffers, my question is where is the flaw in the logic that you either use a faster chip or you spent extra time writing more efficient software.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
关于应该使用 StringBuffer 而不是串联的论点是一个古老的 Java 货物崇拜神话。 Java 编译器本身会将一系列串联转换为单个 StringBuffer 调用,从而使源代码中完全不需要这种“优化”。
话虽如此,即使您使用“慢”字节码或解释语言,也有合理的理由进行优化。您不想处理 C/C++ 的 bug、不稳定和较长的开发周期,因此您使用功能更丰富的语言。 (内置字符串,哇!)但同时,您希望代码使用该语言尽可能快地运行,因此您可以避免明显低效的构造。 IOW 仅仅因为您使用 java 放弃了一些速度,并不意味着您应该完全忘记性能。
The argument that you should use StringBuffer rather than concatenation is an old java cargo-cult myth. The Java compiler itself will convert a series of concatenations into a single StringBuffer call, making this "optimization" completely unnecessary in source code.
Having said that, there are legitimate reasons to optimize even if you're using a "slow" bytecode or interpreted language. You don't want to deal with the bugs, instability, and longer development cycle of C/C++, so you use a language with richer capabilities. (Built-in strings, whee!) But at the same time, you want your code to run as fast as possible with that language, so you avoid obviously inefficient constructs. IOWs just because you're giving up some speed by using java doesn't mean that you should forget about performance entirely.
不同之处在于,使用 StringBuffer 并不比连接字符串更困难或更耗时。一般原则是,如果可以在不增加开发时间/难度的情况下提高效率,则应该这样做:您的原则仅适用于不可能的情况。
The difference is that StringBuffer is not at all harder or more time-consuming to use than concatenating strings. The general principle is that if it's possible to gain efficiency without increasing development time/difficulty, it should be done: your principle only applies when that's not possible.
语言速度较慢并不是使用速度慢得多的算法的借口(Java 现在也没有那么慢了)。
如果我们将 1 个字符连接到一个 n 个字符的字符串,则需要将 n+1 个字符复制到新字符串中。如果我们
这样做,那么运行时间将是 O(N2)。
相比之下,字符串缓冲区维护一个可变缓冲区,从而将运行时间减少到 O(N)。
您无法将 CPU 加倍以将二次算法简化为线性算法。
(尽管优化器可能已经隐式地为您创建了一个 StringBuffer。)
The language being slower isn't an excuse to use a much slower algorithm (and Java isn't that slow these days).
If we concatenate a 1-character to an n-character string, we need to copy n+1 characters into the new string. If we do
then the running time will be O(N2).
By contrast, a string buffer maintain a mutable buffer which reduces the running time to O(N).
You cannot double the CPU to reduce a quadratic algorithm into a linear one.
(Although the optimizer may have implicitly created a StringBuffer for you already.)
Java!=低效的代码。
您不会购买更快的处理器来避免编写高效的代码。一个糟糕的程序员无论使用什么语言都会写出糟糕的代码。 C/C++ 比 Java 更高效的论点已经是一个老论点了,现在已经不再重要了。
Java != ineffecient code.
You do not buy a faster processor to avoid writing efficient code. A bad programmer will write bad code regardless of language. The argument that C/C++ is more efficient than Java is an old argument that does not matter anymore.
在现实世界中,编程语言、操作系统和开发工具并不是由实际处理它们的人选择的。
A 公司的某个推销员与你的老板共进午餐,推销其操作系统……然后其他推销员邀请你的老板去脱衣舞场推销其数据库引擎……等等。
然后,只有到那时,他们才会雇佣一群程序员将所有这些整合在一起。他们希望它又好又快又便宜。
这就是为什么您最终可能会在移动设备上使用 Java 编写高端性能应用程序,或者在 Windows 上使用 Python 编写精美的 3D 图形……
所以,您的权利,但这并不重要。 :)
In the real world, programming languages, operating systems and developpement tools are not selected by the peoples who will actually deal with it.
Some salesman of company A have lunch with your boss to sell its operating system ... and then some other salesman invite your boss at the strippers to sell its database engine ... and so on.
Then, and only then, they hire a bunch of programmers to put all that together. They want it nice, fast and cheap.
That's why you may end up programming high end performance applications with Java on a mobile device or nice 3D graphics on Windows with Python ...
So, your right, but it doesn't matter. :)
您应该始终尽可能地进行优化。你不应该仅仅因为你有一个快速处理器而“懒惰编码”......
我真的不知道 stringbuffer 是如何工作的,我也不使用 Java,但假设 java 将字符串定义为 char[],你'在执行 str1+str2+str3+str4+str5 时重新分配大量虚拟字符串,您实际上只需要制作一个长度为 str1.length+...str5.length 的字符串并复制所有内容一次...
但是,一个聪明的方法编译器会优化并自动使用 stringbuffer
You should always put optimizations where you can. You shouldn't be "lazy coding" just because you have a fast processor...
I don't really know how stringbuffer works, nor do i work with Java, but assuming that java defines a string as char[], you're allocating a ton of dummy strings when doing str1+str2+str3+str4+str5, where you really only need to make a string of length str1.length+...str5.length and copy everything ONCE...
However, a smart compiler would optimize and automatically use stringbuffer
开发人员应该了解他们的编码选择对性能的影响。
编写导致非线性性能的算法并不是非常困难 - 多项式、指数或更差。如果您在某种程度上不了解语言、编译器和库如何支持您的算法,您可能会陷入任何处理能力都无法摆脱的陷阱。运行时间或内存使用量呈指数级增长的算法可能很快就会超出任何硬件在合理时间内执行的能力。
假设硬件可以扩展到设计不良的算法/编码选择是一个坏主意。以将 100,000 个小字符串连接在一起的循环为例(例如连接到 XML 消息中)。这并不是一种罕见的情况 - 但是当使用单独的字符串连接(而不是 StringBuffer)实现时,这将导致垃圾收集器必须处理的 99,999 个大小不断增加的中间字符串。如果没有足够的内存,这很容易使操作失败,或者充其量只是永远运行。
在上面的示例中,一些 Java 编译器通常(但并非总是)重写代码以在幕后使用 StringBuffer - 但这是例外,而不是规则。在许多情况下,编译器根本无法推断开发人员的意图 - 编写高效代码就成为开发人员的责任。
最后一点 - 编写高效的代码并不意味着花费所有时间寻找微观优化。 过早的优化是编写优秀代码的敌人。但是,您不应将过早优化与了解算法在时间/存储方面的 O() 性能以及在哪种情况下使用哪种算法或设计做出正确选择相混淆。
作为开发人员,您不能忽视这一级别的知识,并假设您始终可以投入更多硬件。
Developers should understand the performance implications of their coding choices.
It's not terribly difficult to write an algorithm that results in non-linear performance - polynomial, exponential or worse. If you don't understand to some extent how the language, compiler, and libraries support your algorithm you can fall into trap that no amount of processing power will dig you out of. Algorithms whose runtime or memory usage is exponential can quickly exceed the ability of any hardware to execute in a reasonable time.
Assuming that hardware can scale to a poorly designed algorithm/coding choice is a bad idea. Take for example a loop that concatenates 100,000 small strings together (say into an XML message). This is not an uncommon situation - but when implementing using individual string concatenations (rather than a StringBuffer) this will result in 99,999 intermediate strings of increasing size that the garbage collector has to dispose of. This can easily make the operation fail if there's not enough memory - or at best just take forever to run.
Now in the above example, some Java compilers can usually (but not always) rewrite the code to use a StringBuffer behind the scenes - but this is the exception, not the rule. In many situations the compiler simply cannot infer the intent of the developer - and it becomes the developer's responsibility to write efficient code.
One last comment - writing efficient code does not mean spending all your time looking for micro-optimizations. Premature optimization is the enemy of writing good code. However, you shouldn't confuse premature optimization with understanding the O() performance of an algorithm in terms of time/storage and making good choices about which algorithm or design to use in which situation.
As a developer you cannot ignore this level of knowledge and just assume that you can always throw more hardware at it.