Java charAt() 还是子字符串?哪个更快?
我想遍历字符串中的每个字符并将字符串的每个字符作为字符串传递给另一个函数。
String s = "abcdefg";
for(int i = 0; i < s.length(); i++){
newFunction(s.substring(i, i+1));}
或者
String s = "abcdefg";
for(int i = 0; i < s.length(); i++){
newFunction(Character.toString(s.charAt(i)));}
最终结果需要是一个字符串。
那么你知道哪个会更快或更有效吗?
I want to go through each character in a String and pass each character of the String as a String to another function.
String s = "abcdefg";
for(int i = 0; i < s.length(); i++){
newFunction(s.substring(i, i+1));}
or
String s = "abcdefg";
for(int i = 0; i < s.length(); i++){
newFunction(Character.toString(s.charAt(i)));}
The final result needs to be a String.
So any idea which will be faster or more efficient?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
像往常一样:没关系,但如果您坚持花时间进行微优化,或者您真的喜欢针对非常特殊的用例进行优化,请尝试以下操作:
As usual: it doesn't matter but if you insist on spending time on micro-optimization or if you really like to optimize for your very special use case, try this:
答案是:没关系。
分析您的代码。这是你的瓶颈吗?
The answer is: it doesn't matter.
Profile your code. Is this your bottleneck?
newFunction
真的需要采用String
吗?如果您可以让newFunction
接受一个char
并像这样调用它,那就更好了:这样,您就可以避免创建临时 String 对象。
回答你的问题:很难说哪个更有效率。在这两个示例中,都必须创建一个仅包含一个字符的
String
对象。哪个更有效取决于String.substring(...)
和Character.toString(...)
在您的特定 Java 实现上的具体实现方式。找到它的唯一方法是通过分析器运行程序并查看哪个版本使用更多的 CPU 和/或更多的内存。通常,您不应该担心这样的微观优化 - 只有当您发现这是性能和/或内存问题的原因时才花时间在这上面。Does
newFunction
really need to take aString
? It would be better if you could makenewFunction
take achar
and call it like this:That way, you avoid creating a temporary String object.
To answer your question: It's hard to say which one is more efficient. In both examples, a
String
object has to be created which contains only one character. Which is more efficient depends on how exactlyString.substring(...)
andCharacter.toString(...)
are implemented on your particular Java implementation. The only way to find it out is running your program through a profiler and seeing which version uses more CPU and/or more memory. Normally, you shouldn't worry about micro-optimizations like this - only spend time on this when you've discovered that this is the cause of a performance and/or memory problem.对于你发布的两个片段,我不想说。我同意 Will 的观点,即它几乎肯定与代码的整体性能无关 - 如果不是,您可以进行更改并自行确定在您的硬件上使用 JVM 时哪个对您的数据来说是最快的。
也就是说,如果您首先将 String 转换为 char 数组,然后对该数组执行迭代,那么第二个片段可能会更好。这样做只会执行一次字符串开销(转换为数组),而不是每次调用。此外,您可以使用一些索引将数组直接传递给 String 构造函数,这比取出数组的 char out 来单独传递它(然后将其转换为一个字符数组)更有效):
但是为了强调我的第一点,当你查看每次调用 String.charAt() 时实际避免的内容时 - 它是两个边界检查,一个(惰性)布尔 OR 和一个添加。这不会产生任何明显的差异。 String 构造函数也没有区别。
从本质上讲,这两种习惯用法在性能方面都很好(两者都不是立即明显低效的),因此您不应该花更多的时间在它们上,除非分析器显示这占用了应用程序的大量运行时间。即便如此,您几乎肯定可以通过重构该领域的支持代码来获得更多性能提升(例如让
newFunction
获取整个字符串本身);到目前为止,java.lang.String 已经得到了很好的优化。Of the two snippets you've posted, I wouldn't want to say. I'd agree with Will that it almost certainly is irrelevant in the overall performance of your code - and if it's not, you can just make the change and determine for yourself which is fastest for your data with your JVM on your hardware.
That said, it's likely that the second snippet would be better if you converted the String into a char array first, and then performed your iterations over the array. Doing it this way would perform the String overhead once only (converting to the array) instead of every call. Additionally, you could then pass the array directly to the String constructor with some indices, which is more efficient than taking a char out of an array to pass it individually (which then gets turned into a one character array):
But to reinforce my first point, when you look at what you're actually avoiding on each call of
String.charAt()
- it's two bounds checks, a (lazy) boolean OR, and an addition. This is not going to make any noticeable difference. Neither is the difference in the String constructors.Essentially, both idioms are fine in terms of performance (neither is immediately obviously inefficient) so you should not spend any more time working on them unless a profiler shows that this takes up a large amount of your application's runtime. And even then you could almost certainly get more performance gains by restructuring your supporting code in this area (e.g. have
newFunction
take the whole string itself); java.lang.String is pretty well optimised by this point.我首先使用 String.toCharArray() 从源 String 获取底层 char[],然后继续调用 newFunction。
但我确实同意 Jesper 的观点,即最好只处理字符并避免所有 String 函数......
I would first obtain the underlying char[] from the source String using String.toCharArray() and then proceed to call newFunction.
But I do agree with Jesper that it would be best if you could just deal with characters and avoid all the String functions...
Leetcode 似乎更喜欢此处的子字符串选项。
这就是我解决这个问题的方法:
}
这是他们给出的最佳解决方案:
}
老实说,我不明白为什么它很重要。
Leetcode seems to prefer the substring option here.
This is how I solved that problem:
}
And this is the optimal solution they give:
}
Honestly, I can't figure out why it would matter.