Я начал работать над новым проектом, связанным с большими данными, для моей стажировки. Мои менеджеры рекомендовали начать изучать функциональное программирование (они настоятельно рекомендовали Scala). У меня был скромный опыт использования F #, но я не мог понять, насколько важно использовать эту парадигму программирования, поскольку в некоторых случаях это дорого.
Дин выступил с интересной лекцией на эту тему и поделился своими мыслями о том, почему «Большие данные» здесь: http://www.youtube.com/watch?v=DFAdLCqDbLQ Но это было не очень удобно, поскольку большие данные не означают только Hadoop.
Как BigData это очень расплывчатое понятие. Я забыл это на некоторое время. Я попытался придумать один простой пример для сравнения различных аспектов, когда мы имеем дело с данными, чтобы увидеть, дорогой ли функциональный способ или нет. Если функциональное программирование дорого и занимает много памяти для небольших данных, зачем нам оно для больших данных?
Вдали от причудливых инструментов я пытался создать решение для одной конкретной и популярной проблемы, используя три подхода: императивный и функциональный (рекурсия, использование коллекций). Я сравнил время и сложность, чтобы сравнить три подхода.
Я использовал Scala для написания этих функций, так как это лучший инструмент для написания алгоритма с использованием трех парадигм
def main(args: Array[String]) {
val start = System.currentTimeMillis()
// Fibonacci_P
val s = Fibonacci_P(400000000)
val end = System.currentTimeMillis()
println("Functional way: \n the Fibonacci sequence whose values do not exceed four million : %d \n Time : %d ".format(s, end - start))
val start2 = System.currentTimeMillis()
// Fibonacci_I
val s2 = Fibonacci_I(40000000 0)
val end2 = System.currentTimeMillis();
println("Imperative way: \n the Fibonacci sequence whose values do not exceed four million : %d \n Time : %d ".format(s2, end2 - start2))
}
Функциональный способ:
def Fibonacci_P(max: BigInt): BigInt = {
//http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Stream
//lazy val Fibonaccis: Stream[Long] = 0 #:: 1 #:: Fibonaccis.zip(Fibonaccis.tail).map { case (a, b) => a + b }
lazy val fibs: Stream[BigInt] = BigInt(0)#::BigInt(1)#::fibs.zip(fibs.tail).map {
n = > n._1 + n._2
}
// println(fibs.takeWhile(p => p < max).toList)
fibs.takeWhile(p = > p < max).foldLeft(BigInt(0))(_ + _)
}
Рекурсивный способ:
def Fibonacci_R(n: Int): BigInt = n match {
case 1 | 2 = > 1
case _ = > Fibonacci_R(n - 1) + Fibonacci_R(n - 2)
}
Повелительный путь:
def Fibonacci_I(max: BigInt): BigInt = {
var first_element: BigInt = 0
var second_element: BigInt = 1
var sum: BigInt = 0
while (second_element < max) {
sum += second_element
second_element = first_element + second_element
first_element = second_element - first_element
}
//Return
sum
}
Я заметил, что функциональное программирование тяжело! это занимает больше времени и занимает больше места в памяти. Я смущен, когда я читаю статью или смотрю доклад, они говорят, что мы должны использовать функциональное программирование в науке о данных. Правда, это проще и продуктивнее, особенно в мире данных. но это занимает больше времени и больше памяти.
Итак, почему мы должны использовать функциональное программирование в больших данных? Каковы лучшие практики использования функционального программирования (Scala) для больших данных?