对于我的数据结构类中的项目,我们必须使用广度优先和深度优先遍历来遍历图形。在这种情况下,深度优先遍历通常在1到100,000个节点之间。
每个节点的内容都是一个字符串。遍历图表并找到解决方案并不是一个大问题。但是,一旦遍历完成,就必须显示它。
为此,我返回每个节点的父节点,并将节点的字符串添加到Stack。在这一点上,代码运行正常(据我所知)。尝试显示这些字符串时会出现大幅减速。
如果堆叠了数万个字符串,我该如何显示它们?直接调用System.out.println()需要太长时间。然而迭代地使用StringBuilder会以某种方式消耗内存。我试图以相当随意的间隔(以相当粗暴的方式)清除StringBuilder,这似乎有点帮助。同样引入一个小睡眠似乎也有帮助。无论哪种方式,当函数完成打印时,Java已经耗尽内存,或者速度极慢而且没有响应。
有没有什么方法可以重构这段代码,以相对及时的方式输出所有字符串(~10秒不应该要求太多),而不会崩溃VM?
if(DFSResult.hash().equals(myPuzzle.answerHash()))
{
System.out.println("Success");
int depth = 0;
while(DFSResult.parent != null)
{
depth++;
if(in.equals("y")) dfs.push(DFSResult.hash());
DFSResult = DFSResult.parent;
}
System.out.println("found at a depth of "+depth+"\n\n");
StringBuilder s = new StringBuilder();
int x = 0;
boolean isSure = false;
if(in.equals("y"))
{
System.out.println("Are you really sure you want to print out a lineage this long? (y/n)");
try{
if(input.readLine().toLowerCase().equals("y"))isSure = true;
}catch (Exception e) {
}//
}
s = new StringBuilder();
while(!dfs.empty() && isSure)
{
//System.out.println(dfs.pop());
s.append(dfs.pop()).append("\n");
x++;
if(x % 500 == 0)
{//Flush the stringbuilder
try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}
System.out.println(s.toString());
s.delete(0,s.length());//supposed 25% efficiency increase over saying s = new StringBuilder()
}
}
System.out.println(s.toString());
答案 0 :(得分:1)
您的示例中不需要使用StringBuilder。 而只是做:
System.out.println(dfs.pop());
循环中的。也不需要睡觉。循环中只有一行。
System.out.println()效率没有问题。请考虑以下代码:
public class TestMain {
public static void main(String[] args) {
long timeBefore = System.currentTimeMillis();
for (int i = 0; i < 50000; i++) {
System.out.println("Value = " + i);
}
long timeAfter = System.currentTimeMillis();
System.out.println("Time elapsed (ms): " + (timeAfter - timeBefore));
}
}
这是我机器上的最后一行输出:
. . .
Value = 49994
Value = 49995
Value = 49996
Value = 49997
Value = 49998
Value = 49999
Time elapsed (ms): 538
你可以看到它超级快。问题不在println()方法中。
下面的堆栈使用示例:
public static void main(String[] args) {
long timeBefore1 = System.currentTimeMillis();
Stack<String> s = new Stack<String>();
for (int i = 0; i < 50000; i++) {
s.push("Value = " + i);
}
long timeAfter1 = System.currentTimeMillis();
long timeBefore2 = System.currentTimeMillis();
while (!s.isEmpty()) {
System.out.println(s.pop());
}
long timeAfter2 = System.currentTimeMillis();
System.out.println("Time spent on building stack (ms): " + (timeAfter1 - timeBefore1));
System.out.println("Time spent on reading stack (ms): " + (timeAfter2 - timeBefore2));
}
输出:
. . .
Value = 2
Value = 1
Value = 0
Time spent on building stack (ms): 31
Time spent on reading stack (ms): 551