我正在解决一个 codeforces 问题(here),但我放弃了。我阅读了社论并实现了解决方案,但在 Java 11 上运行仍然超时(超过 2000 毫秒)。注意到有人让它与类似的解决方案一起工作在 Java 17 上,它也对我有用(运行时间约为 300 毫秒)。基本上,我想知道 Java 中可能添加了哪些内容来导致这种差异,如果有的话,我可以更改我的代码,以便它可以在Java 11 也是如此。
这是代码。
import java.io.*;
import java.lang.reflect.Array;
import java.util.*;
public class Four {
static PrintWriter pw = new PrintWriter(System.out);
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t=Integer.parseInt(br.readLine());
StringBuilder sb=new StringBuilder();
for (int i=0; i<t; i++) {
int size = Integer.parseInt(br.readLine());
long[] end = Arrays.stream(br.readLine().split(" ")).mapToLong(Long::parseLong).toArray();
Arrays.sort(end);
if (solve(end))
sb.append("YES\n");
else
sb.append("NO\n");
}
pw.println(sb);
pw.close();
}
public static boolean solve(long[] a) {
if (a[0]!=1)
return false;
long sum=1;
for (int i=1; i<a.length; i++) {
if (a[i]>sum)
return false;
sum+=a[i];
}
return true;
}
}
我猜这与排序方法或添加长整型有关,但我不确定。我还认为这是一些奇怪的 Java 11 低效率,而不是算法的实际问题,因为我认为我的代码是 O(n log n) 并且所有 n 的总和小于问题中指定的 10^5 所以它应该跑2秒以内没问题吗?
很难知道为什么其他人(例如 Codeforce 的)Java 11 和 17 平台 更快/更慢。您不知道它们在什么硬件上运行、它们使用什么 JVM 选项等等。然后还有一个问题,Java 11 和 17 是不同的......并且它们之间有很多差异。 (3 年、6 个版本和许多人年的开发人员工作。)
我的直觉是,这要么是转移注意力(即平台问题),要么与 JVM 启动和预热开销有关。由于差异与您报告的一样大,我更倾向于前一种解释。
现在处理这个问题的“正常”方法是编写一个基准测试,多次运行算法,消除异常值,然后对其余值进行平均。使用 JMH 或类似的框架来处理机制... 然后在具有相同 JVM 选项的相同硬件上使用 Java 11 和 17 运行基准测试,并比较结果。如果 Java 11 和 17 之间确实存在差异,那么它应该会显示在那里。然后您可以调查差异的原因;例如通过分析。
您在竞争性编程平台上遇到的问题并不代表现实世界的 Java 编程。大多数真正的 Java 应用程序执行的操作要复杂得多,并且设计为运行很长时间……为 JVM 提供时间来 JIT 编译和优化代码。所以...您在这里看到的性能问题(很可能)与 Java 设计的用例类型无关。
这不太可能是“Java 11 效率低下”。