Comecei a trabalhar em um novo projeto recentemente relacionado ao Big Data para meu estágio. Meus gerentes recomendaram começar a aprender programação funcional (eles recomendaram muito Scala). Tive uma experiência humilde no uso de F #, mas não pude ver a importância de usar esse paradigma de programação, pois, em alguns casos, é caro.
Dean fez uma palestra interessante sobre esse tópico e compartilhou seus pensamentos sobre o porquê de "Big Data" aqui: http://www.youtube.com/watch?v=DFAdLCqDbLQ Mas não foi muito conveniente, pois Big Data não significa somente Hadoop.
Como BigData é um conceito muito vago. Eu esqueço isso por um tempo. Tentei criar um exemplo simples para comparar os diferentes aspectos quando lidamos com dados, para ver se a maneira funcional é cara ou não. Se a programação funcional é cara e consome memória para pequenos dados, por que precisamos dela para Big Data?
Longe de ferramentas sofisticadas, tentei criar uma solução para um problema específico e popular usando três abordagens: maneira imperativa e forma funcional (recursão, usando coleções). Comparei tempo e complexidade, para comparar entre as três abordagens.
Usei o Scala para escrever essas funções, pois é a melhor ferramenta para escrever um algoritmo usando três paradigmas
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))
}
Maneira funcional:
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))(_ + _)
}
Maneira recursiva:
def Fibonacci_R(n: Int): BigInt = n match {
case 1 | 2 = > 1
case _ = > Fibonacci_R(n - 1) + Fibonacci_R(n - 2)
}
Maneira imperativa:
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
}
Notei que a programação funcional é pesada! leva mais tempo e consome mais espaço na memória. Estou confuso, sempre que leio um artigo ou assisto a uma conversa, eles dizem que devemos usar a programação funcional na ciência de dados. É verdade que é mais fácil e produtivo, especialmente no mundo dos dados. mas leva mais tempo e mais espaço de memória.
Então, por que precisamos usar a programação funcional no Big Data? Quais são as melhores práticas para usar a programação funcional (Scala) para Big Data?