快速将已知的排序顺序(旧索引 -> 新索引映射)应用于数组

Quickly apply a known sort order (old index -> new index mapping) to an array

我正在尝试对需要“串联”排序 8 个大型数组的例程进行性能调整,其中一个数组是要排序的数组。

这意味着如果我要遍历我现在排序的对象数组,我想我可以通过以下天真的方式让所有其他数组按相同的顺序排序:

private List<object[]> SortInTandem(IndexedObj[] sortedArray, List<object[]> arraysToSort)
    for(int i = 0; i < sortedArray.length; i++) {
       int originalIndex = sortedArray[i].OriginalIndex;
       // Swap the corresponding index from all other arrays to their new position
       foreach(object[] array in arraysToSort) {
          object temp = array[i];
          array[i] = array[originalIndex];
          array[originalIndex] = temp;
       }
    }
    return arraysToSort; // Returning original arrays sorted in-place
}

我相信上述算法可以得到预期的结果,但感觉效率低于预期。 (作业数量是需要的 3 倍?)

我还考虑了以下最小化分配的方法,但需要分配新数组来存储排序的项目,并垃圾收集旧数组(除非我想出一种在调用之间回收分配的方法):

private List<object[]> SortInTandem(IndexedObj[] sortedArray, List<object[]> arraysToSort) =>
    arraysToSort.Select(array =>
    {
       object[] tandemArray = new object[array.length];   
       for(int i = 0; i < sortedArray.length; i++)
          tandemArray[i] = array[sortedArray[i].OriginalIndex];
    }); // Returning newly-allocated arrays

这种事情是在代码的性能关键区域连续完成的,所以我正在寻找关于如何两全其美的想法。

更多地考虑上面的第二个解决方案(分配新数组)——我想到传入的数组列表也可以在生成排序后的变体后“重新调整用途”,所以我实际上只需要分配一个新数组,然后我可以重用传入的数组来准备其他结果:

// Note the allocated arraysToSort passed in will be repurposed to produced a new set of sorted
// arrays, so the caller must be sure to discard their references and only use what is returned.
private List<object[]> SortInTandem(IndexedObj[] sortedArray, List<object[]> arraysToSort)
{
    List<object[]> sortedArrays = new List<object[]>(arraysToSort.Count);
    object[] tandemArray = new object[array.length];
    for(int i = 0; i < arraysToSort.Count; i++)
    {  
       for(int j = 0; j < sortedArray.length; j++)
          tandemArray[j] = array[sortedArray[j].OriginalIndex];
       sortedArrays.Add(tandemArray);
       tandemArray = arraysToSort[i];
    }
    return sortedArrays; // Returning one newly-allocated + all but one original arrays repurposed
}