不好用非常大的字符串? (JAVA) [英] Bad to use very large strings? (Java)
问题描述
创建大字符串是否有任何负面影响?例如,如果我们从一个可能很大的文本文件中读取文本:
Are there any negatives to creating huge strings? For instance, if we're reading in text from a potentially huge text file:
while (scanner.hasNext()) {
someString += scanner.next();
}
// do something cool with someString
处理文件行by line(通常)是一个更好的解决方案,为什么?
Would processing the file line by line be (generally) a better solution, and why?
谢谢
推荐答案
Streaming vs not
当您可以流式传输时,您可以处理任何大小的文件(假设你真的可以忘记你已经看过的所有数据。你最终会得到一个自然的O(n)复杂性,这是一件非常好的事情。你不会因内存不足而中断。
When you can stream, you can handle files of any size (assuming you really can forget all the data you've already seen). You end up with a naturally O(n) complexity, which is a very good thing. You don't break by running out of memory.
流媒体很可爱......但在每种情况下都不起作用。
Streaming is lovely... but doesn't work in every scenario.
StringBuilder
因为似乎对 StringBuilder有一定的争议
建议,这是显示效果的基准。为了让慢速版本在合理的时间内完成,我不得不减小基准的大小。
As it seems there's been a certain amount of controversy over the StringBuilder
advice, here's a benchmark to show the effects. I had to reduce the size of the benchmark in order to get the slow version to even finish in a reasonable time.
首先是结果,然后是代码。这是一个非常粗略和准备好的基准,但结果足够引人注目......
Results first, then code. This is a very rough and ready benchmark, but the results are dramatic enough to make the point...
c:\Users\Jon\Test>java Test slow
Building a string of length 120000 without StringBuilder took 21763ms
c:\Users\Jon\Test>java Test fast
Building a string of length 120000 with StringBuilder took 7ms
代码......
class FakeScanner
{
private int linesLeft;
private final String line;
public FakeScanner(String line, int count)
{
linesLeft = count;
this.line = line;
}
public boolean hasNext()
{
return linesLeft > 0;
}
public String next()
{
linesLeft--;
return line;
}
}
public class Test
{
public static void main(String[] args)
{
FakeScanner scanner = new FakeScanner("test", 30000);
boolean useStringBuilder = "fast".equals(args[0]);
// Accurate enough for this test
long start = System.currentTimeMillis();
String someString;
if (useStringBuilder)
{
StringBuilder builder = new StringBuilder();
while (scanner.hasNext())
{
builder.append(scanner.next());
}
someString = builder.toString();
}
else
{
someString = "";
while (scanner.hasNext())
{
someString += scanner.next();
}
}
long end = System.currentTimeMillis();
System.out.println("Building a string of length "
+ someString.length()
+ (useStringBuilder ? " with" : " without")
+ " StringBuilder took " + (end - start) + "ms");
}
}
这篇关于不好用非常大的字符串? (JAVA)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!