mar*_*ler 0 java arrays arraylist
public static ArrayList<Integer> duplicates(int[] arr) {
ArrayList<Integer> doubles = new ArrayList<Integer>();
boolean isEmpty = true;
for(int i = 0; i<arr.length; i++) {
for (int j = i+1; j< arr.length; j++) {
if( arr[i] == arr[j] && !doubles.contains(arr[i]) ){
doubles.add(arr[i]);
isEmpty = false;
break;
}
}
}
if(isEmpty) doubles.add(-1);
Collections.sort(doubles);
return doubles;
}
public static void main(String[] args) {
System.out.println( ( duplicates( new int[]{1,2,3,4,4,4} ) ) ); // Return: [4]
}
Run Code Online (Sandbox Code Playgroud)
我用 Java 创建了这个函数,它返回输入 int 数组的倍数,如果输入数组为空或没有倍数,则返回 -1。
它有效,但可能有一种方法可以让它更快。是否有任何好的做法可以使函数总体上更高效、更快?
概括地说,您可以进行 2 项完全不相关的性能改进:
第一个很简单,但可能会产生误导:您可以编写一个算法,以算法上不太复杂的方式完成相同的工作,但实际上运行速度较慢。
第二个也很棘手:你的眼球和大脑无法完成这项工作。编写 JVM 本身的工程师曾公开表示,他们通常不知道任何给定代码的实际运行速度有多快。这是因为 JVM太复杂了:它有很多复杂的途径来优化东西的运行速度(不仅是支持这些东西的代码复杂,而且它们的工作方式也很复杂。例如,热点最终启动,并使用以前运行的特征来确定如何最好地将给定方法重写为经过微调的机器代码,并且运行它的硬件也很重要)。
这得出以下简单的结论:
对于这个特定的算法,鉴于我不知道合理的输入可能是什么,您将必须完成设置 JMH 和/或探查器运行的工作。然而,就算法复杂性而言:
该doubles.contains调用的算法复杂度为 O(N):调用所需的时间与输入的大小成线性关系。
如果您使用 HashSet,则可以获得 O(1) 的算法复杂度。
从单纯的性能角度来看,通常 ArrayList 的性能和内存负载与 ArrayList 相比int[]是相当大的。
这给出了 2 个替代的明显策略来优化此代码:
ArrayList<Integer>为int[].ArrayList<integer>a HashSet<Integer>。如果不花费大量时间来处理原始 int 数组支持的 hashbucket 实现,您就无法真正将这两者结合起来。幸运的是,有人为您完成了这项工作:Eclipse Collections 有一个原始的 int hashset 实现。
理论上很难想象用 IntHashSet 替换它会慢多少。然而,我不能公开向你保证它会更快:我可以想象如果你的输入是一个包含几百万个整数的 int 数组,IntHashSet 可能会快很多个数量级。但您确实需要测试数据和探查器报告和/或 JMH 运行,否则我们都只是猜测,考虑到 JVM 是如此复杂,这是一个坏主意。
所以,如果你真的想优化这个:
| 归档时间: |
|
| 查看次数: |
383 次 |
| 最近记录: |