Index: lucene/core/src/java/org/apache/lucene/search/spans/NearSpansOrdered.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/search/spans/NearSpansOrdered.java	(revision 1507337)
+++ lucene/core/src/java/org/apache/lucene/search/spans/NearSpansOrdered.java	(working copy)
@@ -22,6 +22,7 @@
 import org.apache.lucene.index.TermContext;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.InPlaceMergeSorter;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -72,13 +73,19 @@
   private List<byte[]> matchPayload;
 
   private final Spans[] subSpansByDoc;
-  private final Comparator<Spans> spanDocComparator = new Comparator<Spans>() {
+  // Even though the array is probably almost sorted, InPlaceMergeSorter will likely
+  // perform better since it has a lower overhead than TimSorter for small arrays
+  private final InPlaceMergeSorter sorter = new InPlaceMergeSorter() {
     @Override
-    public int compare(Spans o1, Spans o2) {
-      return o1.doc() - o2.doc();
+    protected void swap(int i, int j) {
+      ArrayUtil.swap(subSpansByDoc, i, j);
     }
+    @Override
+    protected int compare(int i, int j) {
+      return subSpansByDoc[i].doc() - subSpansByDoc[j].doc();
+    }
   };
-  
+
   private SpanNearQuery query;
   private boolean collectPayloads = true;
   
@@ -204,7 +211,7 @@
 
   /** Advance the subSpans to the same document */
   private boolean toSameDoc() throws IOException {
-    ArrayUtil.timSort(subSpansByDoc, spanDocComparator);
+    sorter.sort(0, subSpansByDoc.length);
     int firstIndex = 0;
     int maxDoc = subSpansByDoc[subSpansByDoc.length - 1].doc();
     while (subSpansByDoc[firstIndex].doc() != maxDoc) {
