我开始从事与大数据相关的新项目的实习。我的经理们建议开始学习函数式编程(他们强烈推荐Scala)。我使用F#的经验很卑鄙,但是我看不到使用这种编程范例的重要性,因为在某些情况下它很昂贵。
迪恩(Dean)在这个话题上做了有趣的演讲,并在这里分享了他对“大数据”为何的想法: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)用于大数据的最佳实践是什么?