Эффективно ли использовать массивы в рекурсии при функциональном программировании на scala? - PullRequest
0 голосов
/ 23 апреля 2020

Если использовать функциональный подход, это самый эффективный способ сделать это?

@tailrec
def readLine(in: SomeTypeOfBuffer, a: Array[Byte]): Array[Byte] = {
    val char = in.readByte()
    char match{
        case '\n'  => a 
        case other => readLine(in, a :+ other) 
    }

}

Поскольку каждый рекурсивный вызов создает новый массив, необходимо сделать еще один вызов памяти, чтобы выделить место для другого массив, а предыдущий массив освобожден из памяти.

Это просто цена функционального программирования?

(я относительно новичок в scala и функционален, поэтому, пожалуйста, не распинайте меня, если я что-то ужасно неправильно)

Ответы [ 3 ]

0 голосов
/ 23 апреля 2020

Как сказал @DeFuncT, лучше использовать (неизменяемый) Список , поскольку он не будет копировать данные при построении. Я просто покажу вам, как это сделать.

Я также собираюсь применить совет от @ QuickSilver.

def readLine(in: SomeTypeOfBuffer): List[Byte] = {
  val NewLine: Byte = '\n'.toByte

  @annotation.tailrec
  def loop(acc: List[Byte]): List[Byte]
    in.readByte() match {
      case NewLine => acc.reverse
      case char    => loop(other :: acc)
    }

  loop(acc = List.empty)
}

PS: в общем Scala, вы никогда не увидите Массив . Возможно, новые ArraySeq или Vector .
Простые массивы обычно используются только из соображений производительности и обычно содержатся в области действия одного метода.

0 голосов
/ 23 апреля 2020

Нет ничего плохого в использовании внутренней изменчивости для эффективности и обеспечении безопасного неизменяемого API:

@tailrec
private def readLineInner(in: DataInputStream, a: ArrayBuffer[Byte]): Array[Byte] = {
    val char = in.readByte()
    char match{
      case '\n'  => a.toArray
      case other => {
        a.addOne(other)
        readLineInner(in, a )
      }
    }
}

def readLine(in: DataInputStream): Array[Byte] =
  readLineInner(in, new ArrayBuffer[Byte]())
0 голосов
/ 23 апреля 2020

Лучше использовать List в вашей ситуации, так как List внутренне является в основном связанным списком, а добавление в связанный список - O (1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...