我目前正在编写一个Android应用程序来比较不同数据结构和算法之间的运行时间。当我运行我的应用程序并开始计算不同数据结构的运行时测试时,即使n的大小为100,应用程序也会耗尽内存。运行速度非常慢并且应用程序内存不足的唯一部分是在调用时获取运行时的静态方法。当我在Eclipse上运行它时速度非常快。
这里是logcat的一部分(当n = 100时,仅使用静态方法获取ArrayList的运行时间约1分钟):
02-03 19:02:02.853 316-685/? D/AudioFlinger﹕ mixer(0xb2140000) throttle end: throttle time(11)
02-03 19:02:02.958 3363-3373/? I/art﹕ Background partial concurrent mark sweep GC freed 12383(516KB) AllocSpace objects, 0(0B) LOS objects, 40% free, 9MB/16MB, paused 5.218ms total 54.521ms
02-03 19:02:03.159 3363-3373/? I/art﹕ Background sticky concurrent mark sweep GC freed 71554(1274KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 19MB/19MB, paused 7.547ms total 98.376ms
02-03 19:02:03.281 3363-3373/? I/art﹕ Background partial concurrent mark sweep GC freed 66258(1895KB) AllocSpace objects, 0(0B) LOS objects, 40% free, 21MB/36MB, paused 9.116ms total 121.088ms
02-03 19:02:03.350 3363-3363/? D/RunTimeComparison﹕ List selected
02-03 19:03:29.714 3363-3363/? D/RunTimeComparison﹕ Added arrayList entries
当用户点击"测试运行"此方法将运行数据结构的按钮:
private void runDataStructuresComparison(int n) {
String dsType = dsTypeSpinner.getSelectedItem().toString();
List<Integer> arrayList = new ArrayList<Integer>();
List<Integer> linkedList = new LinkedList<Integer>();
Set<Integer> hashSet = new HashSet<Integer>();
Set<Integer> treeSet = new TreeSet<Integer>();
Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
Map<Integer, Integer> treeMap = new TreeMap<Integer, Integer>();
Random rand = new Random();
for (int i = 0; i < n; i++) {
arrayList.add(i);
linkedList.add(i);
hashSet.add(rand.nextInt(n));
treeSet.add(rand.nextInt(n));
hashMap.put(rand.nextInt(n), i);
treeMap.put(rand.nextInt(n), i);
}
if (dsType.equalsIgnoreCase("Lists")) {
Log.d(TAG, "List selected");
String[] labels = {"Access", "Search", "Random Insertion", "Sequential Insertion",
"Random Deletion", "Sequential Deletion"};
List<BarEntry> arrayListEntries = new ArrayList<>();
arrayListEntries.add(new BarEntry(ListRunTime.accessTime(arrayList, n), 0));
arrayListEntries.add(new BarEntry(ListRunTime.searchTime(arrayList, n), 1));
arrayListEntries.add(new BarEntry(ListRunTime.randomInsertionTime(new ArrayList<Integer>(arrayList), n), 2));
arrayListEntries.add(new BarEntry(ListRunTime.sequentialInsertionTime(new ArrayList<Integer>(arrayList), n), 3));
arrayListEntries.add(new BarEntry(ListRunTime.randomDeletionTime(new ArrayList<Integer>(arrayList), n), 4));
arrayListEntries.add(new BarEntry(ListRunTime.sequentialDeletionTime(new ArrayList<Integer>(arrayList), n), 5));
Log.d(TAG, "Added arrayList entries");
List<BarEntry> linkedListEntries = new ArrayList<>();
linkedListEntries.add(new BarEntry(ListRunTime.accessTime(linkedList, n), 0));
linkedListEntries.add(new BarEntry(ListRunTime.searchTime(linkedList, n), 1));
linkedListEntries.add(new BarEntry(ListRunTime.randomInsertionTime(new LinkedList<Integer>(linkedList), n), 2));
linkedListEntries.add(new BarEntry(ListRunTime.sequentialInsertionTime(new LinkedList<Integer>(linkedList), n), 3));
linkedListEntries.add(new BarEntry(ListRunTime.randomDeletionTime(new LinkedList<Integer>(linkedList), n), 5));
linkedListEntries.add(new BarEntry(ListRunTime.sequentialDeletionTime(new LinkedList<Integer>(linkedList), n), 5));
Log.d(TAG, "Added LinkedList Entries");
BarDataSet arrayListDataSet = new BarDataSet(arrayListEntries, "ArrayList");
BarDataSet linkedListDataSet = new BarDataSet(linkedListEntries, "LinkedList");
Log.d(TAG, "BarDataSet created");
List<IBarDataSet> dataSets = new ArrayList<>();
dataSets.add(arrayListDataSet);
dataSets.add(linkedListDataSet);
BarData data = new BarData(labels, dataSets);
Log.d(TAG, "Prepare to draw");
chart.setData(data);
Log.d(TAG, "Started Drawing Chart");
} else if (dsType.equalsIgnoreCase("Sets")) {
String[] labels = {"Search", "Insertion", "Deletion"};
} else if (dsType.equalsIgnoreCase("Maps")) {
String[] labels = {"Access", "Search", "Insertion", "Deletion"};
}
}
这是一个获取列表运行时的示例类(我使用float时间,因为我使用的图表框架使用了float):
package RunTimeComplexity;
import java.util.List;
import java.util.Random;
public class ListRunTime {
private static final Random RAND = new Random();
public static float accessTime(List<Integer> list, int n) {
Watch.start();
for (int i = 0; i < n; i++) {
list.get(RAND.nextInt(n));
}
return Watch.getTime();
}
public static float searchTime(List<Integer> list, int n) {
Watch.start();
for (int i = 0; i < n; i++) {
list.contains(RAND.nextInt(n));
}
return Watch.getTime();
}
public static float randomInsertionTime(List<Integer> list, int n) {
Watch.start();
for (int i = 0; i < n; i++) {
list.add(RAND.nextInt(n), i);
}
return Watch.getTime();
}
public static float sequentialInsertionTime(List<Integer> list, int n) {
Watch.start();
for (int i = 0; i < n; i++) {
list.add(i);
}
return Watch.getTime();
}
public static float randomDeletionTime(List<Integer> list, int n) {
Watch.start();
for (int i = 0; i < n; i++) {
list.remove(RAND.nextInt(n - i));
}
return Watch.getTime();
}
public static float sequentialDeletionTime(List<Integer> list, int n) {
Watch.start();
for (int i = n - 1; i >= 0; i--) {
list.remove(i);
}
return Watch.getTime();
}
}