如何在Scala中优化此CountingSort算法的计时

如何在Scala中优化此CountingSort算法的计时,scala,median,counting-sort,Scala,Median,Counting Sort,我想请您帮助确定我的代码的哪一部分没有效率。我将快速排序算法与CountingSort算法进行比较,假设数组[Byte]中的元素数小于16 但是,在我按顺序执行的所有测试中,CountingSort时间远高于QuickSort时间。然后,我想在Spark中测试这段代码以计算中值滤波器,但分布式执行时间的结果与顺序执行时间一致。我的意思是,快速排序总是比CountingSort快,即使对于较小的数组也是如此 显然,我的代码中有什么东西挂起了最终的处理 代码如下: def Histogram(Inp

我想请您帮助确定我的代码的哪一部分没有效率。我将快速排序算法与CountingSort算法进行比较,假设
数组[Byte]
中的元素数小于16

但是,在我按顺序执行的所有测试中,CountingSort时间远高于QuickSort时间。然后,我想在Spark中测试这段代码以计算中值滤波器,但分布式执行时间的结果与顺序执行时间一致。我的意思是,快速排序总是比CountingSort快,即使对于较小的数组也是如此

显然,我的代码中有什么东西挂起了最终的处理

代码如下:

def Histogram(Input: Array[Byte]) : Array[Int] = {
  val result = Array.ofDim[Int](256)
  val range = Input.distinct.map(x => x & 0xFF)
  val mx = Input.map(x => x & 0xFF).max
  for (h <- range)
    result(h) = Input.count(x => (x & 0xFF) == h)
  result.slice(0, mx + 1)
}

def CummulativeSum(Input: Array[Int]): Array[Long] = Input.map(x => x.toLong).scanLeft(0.toLong)(_ + _).drop(1)

def CountingSort(Input: Array[Byte]): Array[Byte] = {
  val hist = Histogram(Input)
  val cum = CummulativeSum(hist)
  val Output = Array.fill[Byte](Input.length)(0)
  for (i <- Input.indices) {
    Output(cum(Input(i) & 0xFF).toInt - 1) = Input(i)
    cum(Input(i) & 0xFF) -= 1
  }
  Output
}
def直方图(输入:数组[Byte]):数组[Int]={
val result=Array.ofDim[Int](256)
val range=Input.distinct.map(x=>x&0xFF)
valmx=Input.map(x=>x&0xFF).max
对于(h(x&0xFF)==h)
结果.切片(0,mx+1)
}
def cumulativesum(输入:数组[Int]):数组[Long]=Input.map(x=>x.toLong).scanlight(0.toLong)(+).drop(1)
def CountingSort(输入:数组[字节]):数组[字节]={
val hist=直方图(输入)
val cum=累积量(历史)
val输出=数组.填充[字节](输入.长度)(0)
对于(i您可以构建直方图,而无需多次遍历输入

def histogram(input :Array[Byte]) :Array[Int] = {
  val inputMap :Map[Int,Array[Byte]] = input.groupBy(_ & 0xFF)
                                            .withDefaultValue(Array())
  Array.tabulate(inputMap.keys.max+1)(inputMap(_).length)
}
我不确定这是否快得多,但它肯定更简洁

def countingSort(input :Array[Byte]) :Array[Byte] =
  histogram(input).zipWithIndex.flatMap{case (v,x) => Seq.fill(v)(x.toByte)}

我的测试表明,它产生了相同的结果,但可能有我错过的边缘条件。

计数排序的时间复杂度是
O(n+k)
。如果
k
显著大于
n
(假设n仅为16),那么使用计数排序可能不是最佳选择(也许这就是为什么快速排序优于它的原因。)让我看看我是否明白了。你是说
n=16
很棒吗?我认为
n=1000000
很棒。@cilton对混淆表示抱歉。
O(n+k)
给人的印象是线性时间性能,但只有当
k
远小于
n
时才是如此;因为否则它近似于
O(k)
,这可能比我们的
O(n)
预期差得多。在这种情况下,n只有16,所以如果k是(比如)10000,那么我们将看到O(10000x)而不是O(16x)性能类型感谢您的帮助。我想告诉您,我已经测试了您的代码。不幸的是,虽然您的代码更简洁,但计时性能更差