1. 概述

在这篇简短的文章中,我们将对 Java 中的两个排序方法进行对比:Arrays.sort(Object[])Arrays.sort(int[])

首先,我们会分别介绍这两个方法的实现原理和使用方式。然后通过性能测试,比较它们在实际运行中的效率差异。

2. Arrays.sort(Object[])

在继续之前,需要明确一点:Arrays.sort() 方法可以处理基本类型数组和引用类型数组。

Arrays.sort(Object[]) 是专门用于处理引用类型的数组。

举个例子,我们有一个 Integer 对象数组:

Integer[] numbers = {5, 22, 10, 0};

我们可以直接调用:

Arrays.sort(numbers);

执行后,数组将按升序排列:

[0, 5, 10, 22]

这个方法内部使用的是 TimSort 算法,时间复杂度为 **O(n log n)**。简单来说,TimSort 是插入排序和归并排序的结合体。虽然效率不错,但在多数情况下,它还是比不上一些优化后的快速排序实现。

3. Arrays.sort(int[])

与之相对,Arrays.sort(int[]) 是用于处理基本类型 int 数组的。

我们同样定义一个 int[] 数组:

int[] primitives = {5, 22, 10, 0};

然后调用排序方法:

Arrays.sort(primitives);

结果和前面一样:

[0, 5, 10, 22]

不过,它的底层实现使用的是 双轴快速排序(Dual-Pivot Quicksort)算法。从 JDK 10 开始,这种实现通常比传统的单轴快速排序更快。

该算法的平均时间复杂度同样是 **O(n log n)**,非常适合大多数排序场景。而且它是原地排序,不需要额外的存储空间。

⚠️ 但要注意,在最坏情况下,它的时间复杂度会退化为 **O(n²)**。

4. 性能对比

那么,哪个排序方法更快?我们先从理论上分析,再通过 JMH 实际测试验证。

4.1. 理论分析

通常来说,Arrays.sort(int[]) 会比 Arrays.sort(Object[]) 更快,主要原因如下:

  • 算法差异:快速排序通常比 TimSort 更快
  • 元素比较方式不同:
    • Arrays.sort(Object[]) 需要调用对象的 compareTo() 方法,这涉及到方法调用开销
    • Arrays.sort(int[]) 直接使用原生的 <> 等操作符,是单字节码指令,效率更高

4.2. JMH 配置

为了验证理论,我们使用 JMH(Java Microbenchmark Harness) 来做性能测试。

测试类配置如下:

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Measurement(batchSize = 100000, iterations = 10)
@Warmup(batchSize = 100000, iterations = 10)
public class ArraySortBenchmark {
}

说明:

  • 使用平均时间模式(Mode.AverageTime
  • 时间单位为毫秒(TimeUnit.MILLISECONDS
  • 每轮测试执行 100000 次,共 10 轮,确保结果准确性

4.3. 测试代码

测试前,我们准备数据容器:

@State(Scope.Thread)
public static class Initialize {
    Integer[] numbers = {-769214442, -1283881723, 1504158300, -1260321086, -1800976432, 1278262737, 
      1863224321, 1895424914, 2062768552, -1051922993, 751605209, -1500919212, 2094856518, 
      -1014488489, -931226326, -1677121986, -2080561705, 562424208, -1233745158, 41308167 };
    int[] primitives = {-769214442, -1283881723, 1504158300, -1260321086, -1800976432, 1278262737, 
      1863224321, 1895424914, 2062768552, -1051922993, 751605209, -1500919212, 2094856518, 
      -1014488489, -931226326, -1677121986, -2080561705, 562424208, -1233745158, 41308167};
}

测试方法如下:

@Benchmark
public Integer[] benchmarkArraysIntegerSort(ArraySortBenchmark.Initialize state) {
    Arrays.sort(state.numbers);
    return state.numbers;
}

@Benchmark
public int[] benchmarkArraysIntSort(ArraySortBenchmark.Initialize state) {
    Arrays.sort(state.primitives);
    return state.primitives;
}

4.4. 测试结果

运行测试后,结果如下:

Benchmark                   Mode  Cnt  Score   Error  Units
benchmarkArraysIntSort      avgt   10  1.095 ± 0.022  ms/op
benchmarkArraysIntegerSort  avgt   10  3.858 ± 0.060  ms/op

✅ 可以看到,Arrays.sort(int[]) 明显优于 Arrays.sort(Object[]),符合我们的理论分析。

当然,这只是在特定数据下的测试结果,实际使用中还需根据数据规模、分布等进一步验证。

4.5. 为什么还要用 TimSort?

既然快速排序更快,那为什么 Arrays.sort(Object[]) 不也用它呢?

❌ 因为快速排序是不稳定排序,而 Java 要求对对象数组排序时必须是稳定排序

比如,对一组对象按某个字段排序,如果两个对象该字段值相同,它们的相对顺序不能改变。这种场景下,快速排序就不适用了。

5. 总结

本文对比了 Java 中的两种排序方式:

  • Arrays.sort(int[]) 使用双轴快速排序,速度快,适用于基本类型
  • Arrays.sort(Object[]) 使用 TimSort,稳定但稍慢,适用于对象类型

通过 JMH 测试,我们验证了基本类型排序的性能优势。

如需查看完整代码,可前往 GitHub 项目地址


原始标题:Time Comparison of Arrays.sort(Object[]) and Arrays.sort(int[]) | Baeldung