解决方案:我的ArrayList填充了重复项。我修改了我的代码以过滤掉这些,这将运行时间减少到大约1秒。
我正在研究一个需要我查看大量数据的算法项目。
我的程序有一个非常大的ArrayList(A),它遍历了每个元素。对于(A)中的每个元素,将若干其他计算元素添加到另一个ArrayList(B)中。 (B)将远远大于(A)。
一旦我的程序运行了七个这样的ArrayLists,运行时间就会增加到大约5秒。我试图把它降到< 1秒,如果可能的话。
我愿意以不同的方式遍历ArrayList,以及使用完全不同的数据结构。我不关心列表中值的顺序,只要我能够非常快速地查看所有值。我尝试了一个链表,速度明显慢了。
这是一段代码,可以让您更好地理解。代码试图找到素数的所有单位数排列。
public static Integer primeLoop(ArrayList current, int endVal, int size)
{
Integer compareVal = 0;
Integer currentVal = 0;
Integer tempVal = 0;
int currentSize = current.size()-1;
ArrayList next = new ArrayList();
for(int k = 0; k <= currentSize; k++)
{
currentVal = Integer.parseInt(current.get(k).toString());
for(int i = 1; i <= 5; i++)
{
for(int j = 0; j <= 9; j++)
{
compareVal = orderPrime(currentVal, endVal, i, j);
//System.out.println(compareVal);
if(!compareVal.equals(tempVal) && !currentVal.equals(compareVal))
{
tempVal = compareVal;
next.add(compareVal);
//System.out.println("Inserted: "+compareVal + " with parent: "+currentVal);
if(compareVal.equals(endVal))
{
System.out.println("Separation: " + size);
return -1;
}
}
}
}
}
size++;
//System.out.println(next);
primeLoop(next, endVal, size);
return -1;
}
*编辑:从上面的代码段中删除了不必要的代码。创建了一个currSize变量,用于阻止程序每次都调用(当前)的大小。仍然没有区别。以下是ArrayList如何增长的想法: 2, 29, 249, 2293, 20727, 190819,
答案 0 :(得分:2)
当某些事情变得缓慢时,典型的建议是对其进行分析。这通常是明智的,因为即使对于性能专家来说,通常也很难确定导致缓慢的原因。有时可以选择可能是性能问题的代码,但这是偶然的。此代码中有一些可能的内容,但很难确定,因为我们没有orderPrime()
和primeLoop()
方法的代码。
那说,有一件事引起了我的注意。这一行:
currentVal = Integer.parseInt(current.get(k).toString());
这会从current
获取一个元素,将其转换为字符串,将其解析回int
,然后将其装入Integer
。转换为String和从String转换是非常昂贵的,并且它分配内存,因此它对垃圾收集施加压力。拳击原始int
值到Integer
个对象也会分配内存,从而导致GC压力。
由于您使用原始类型ArrayList
作为current
,因此很难说出修复的内容。我猜测它可能是ArrayList<Integer>
,如果是这样,你可以用
currentVal = (Integer)current.get(k);
你应该使用泛型来避免演员表。 (但这不会影响性能,只会影响代码的可读性和类型安全性。)
如果current
不包含Integer
值,则应该。无论它包含什么,都应该事先转换为Integer
,而不是将转换放在循环中。
修复此问题后,您仍然需要进行装箱/拆箱开销。如果性能仍然存在问题,则必须从ArrayList<Integer>
切换到int[]
,因为Java集合不能包含基元。这很不方便,因为您必须实现自己的类似列表的结构,模拟int
的可变长度数组(或找到执行此操作的第三方库)。
但即使以上所有方法都可能还不足以让你的程序运行得足够快。我不知道你的算法在做什么,但看起来它正在进行线性搜索。有多种方法可以加快搜索速度。但是另一位评论者建议二元搜索,你说这是不允许的,所以不清楚这里可以做些什么。
答案 1 :(得分:1)
为什么你有这一行
current.iterator();
你根本不使用迭代器,你甚至没有变量。这只是时间的推移。
for(int k = 0; k <= current.size()-1; k++)
不是每次迭代计算大小,而是创建如下的值:
int curSize = current.size() - 1;
并在循环中使用它。
它可以节省一些时间。
答案 2 :(得分:1)
以下是关于ArrayList如何发展的想法:2,29,249,2293,20727,190819
您的next
列表变得过大,因此必须包含重复项:
删除重复项肯定会缩短您的响应时间。