Нещодавно я почав працювати над новим проектом, пов’язаним з Big Data, для стажування. Мої менеджери рекомендували почати вивчати функціональне програмування (Вони дуже рекомендують Scala). У мене був принижений досвід використання F #, але я не міг зрозуміти важливості використання цієї парадигми програмування, оскільки це дорого в деяких випадках.
Дін цікаво поговорив на цю тему та поділився своїми думками про те, чому "Big Data" тут: http://www.youtube.com/watch?v=DFAdLCqDbLQ Але це було не дуже зручно, оскільки Big Data не означає тільки Hadoop
Оскільки BigData - це дуже розпливчаста концепція. Я на деякий час це забуваю. Я намагався придумати один простий приклад, щоб порівняти різні аспекти, коли ми маємо справу з даними, щоб побачити, чи є функціональний спосіб дорогим чи ні. Якщо функціональне програмування є дорогим і вимагає багато пам'яті для невеликих даних, то для чого це потрібно для Big Data?
Далеко від фантазійних інструментів я намагався створити рішення для однієї конкретної та популярної проблеми, використовуючи три підходи: імперативний спосіб та функціональний спосіб (рекурсія, використання колекцій). Я порівняв час і складність, щоб порівняти три підходи.
Я використовував 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) для великих даних?