如果该方法引用了其他类的方法,那么计算耗时时要考虑把首次加载时的加载时间排除掉。如以下测试使用了UserIdEncodeUtil类中的方法,它首次使用时才去加载,那么这个加载时间就影响了算法的时间:
public static void main(String[] args) throws ClassNotFoundException {
// Class.forName("util.UserIdEncodeUtil");
List<String> timeList = new ArrayList<>();
List<String> stringList = new ArrayList<>();
double sum = 0;
int loopTime = 10;
for (int j = 0; j < loopTime; j++) {
int len = 40;
StringBuilder builder = new StringBuilder(2048);
long begin = System.nanoTime();
Random random = new Random();
for (int i = 1; i <= len; i++) {
String encodeStr = UserIdEncodeUtil.getEncodeStr(i, random);
builder.append(i).append("=").append(encodeStr).append(", ");
}
stringList.add(builder.toString());
double time = (System.nanoTime() - begin) / 1000000.0;
timeList.add("Time: " + time + " ms");
sum += time;
}
for (String s : stringList) {
System.out.println(s);
}
System.out.println();
for (String s : timeList) {
System.out.println(s);
}
System.out.println("总耗时:" + sum + ",平均耗时:" + sum / loopTime);
}
实际结果毫无意外:
Time: 3.537834 ms
Time: 0.223622 ms
Time: 0.169505 ms
Time: 0.172615 ms
Time: 0.187233 ms
Time: 0.134982 ms
Time: 0.137781 ms
Time: 0.128761 ms
Time: 0.136537 ms
Time: 0.295468 ms
总耗时:5.124338,平均耗时:0.5124337999999999
把main函数第一行的注释去掉,使用Class.forName进行预加载,可以发现情况有了很大的好转:
Time: 0.910039 ms
Time: 0.189722 ms
Time: 0.167016 ms
Time: 0.169194 ms
Time: 0.816423 ms
Time: 0.08242 ms
Time: 0.161107 ms
Time: 0.068424 ms
Time: 0.064692 ms
Time: 0.067802 ms
总耗时:2.6968389999999998,平均耗时:0.2696839
但是可以发现,即便进行预加载了,第一次调用时用的时间还是会长一些,这就不大清楚了,这应该是虚拟机运行机制的问题。虚拟机的问题今后值得去深入学习一下。 |