Why is my implementation of binary search in Scala so slow?

I recently implemented this binary search, which should work for less than 6 seconds for Scala, but it works for 12-13 seconds on a machine that checks the destination.

Note before reading the code: the input consists of two lines: first is a list of numbers to search, and the second is a list of "search conditions" for searching in the list of numbers. The expected result simply lists the indices of each term in a list of numbers. Each input can be a maximum length of 10 ^ 5 and each number a maximum size of 10 ^ 9.

For instance:

Input:
5 1 5 8 12 13 //note, that the first number 5 indicates the length of the 
following sequence

5 8 1 23 1 11 //note, that the first number 5 indicates the length of the 
following sequence

Output:
2 0 -1 0 -1 // index of each term in the input array

My decision:

object BinarySearch extends App {
  val n_items = readLine().split(" ").map(BigInt(_))
  val n = n_items(0)
  val items = n_items.drop(1)

  val k :: terms = readLine().split(" ").map(BigInt(_)).toList

  println(search(terms, items).mkString(" "))

  def search(terms: List[BigInt], items:Array[BigInt]): Array[BigInt] = {
    @tailrec
    def go(terms: List[BigInt], results: Array[BigInt]): Array[BigInt] = terms match {
      case List() => results
      case head :: tail => go(tail, results :+ find(head))
    }

    def find(term: BigInt): BigInt = {
      @tailrec
      def go(left: BigInt, right: BigInt): BigInt = {
        if (left > right) { -1 }
        else {
          val middle = left + (right - left) / 2
          val middle_val = items(middle.toInt)

          middle_val match {
            case m if m == term => middle
            case m if m <= term => go(middle + 1, right)
            case m if m > term => go(left, middle - 1)
          }
        }
      }

      go(0, n - 1)
    }

    go(terms, Array())
  }
}

What makes this code so slow? Thanks you

+4
source share
1 answer

I'm worried about complexity

results :+ find(head)

L O (L) (. ), , n , O (n * n).

ArrayBuffer find.

,

go(terms, Array())

terms.map( x => find(x) ).toArray

, , BigInt , , . ints .

+4

Source: https://habr.com/ru/post/1692790/


All Articles