Gần đây tôi bắt đầu thực hiện một dự án mới liên quan đến Dữ liệu lớn cho kỳ thực tập của mình. Các nhà quản lý của tôi khuyên bạn nên bắt đầu học lập trình chức năng (Họ rất khuyến khích Scala). Tôi đã có một trải nghiệm khiêm tốn khi sử dụng F #, nhưng tôi không thể thấy được tầm quan trọng của việc sử dụng mô hình lập trình này vì nó đắt tiền trong một số trường hợp.
Dean đã có một cuộc nói chuyện thú vị về chủ đề này và chia sẻ suy nghĩ của mình về lý do tại sao "Dữ liệu lớn" ở đây: http://www.youtube.com/watch?v=DFAdLCqDbLQ Nhưng nó không thuận tiện vì Big Data không có nghĩa chỉ Hadoop.
Như BigData là khái niệm rất mơ hồ. Tôi quên nó một lúc. Tôi đã cố gắng đưa ra một ví dụ đơn giản để so sánh giữa các khía cạnh khác nhau khi chúng ta xử lý dữ liệu, để xem liệu cách thức chức năng có đắt hay không. Nếu lập trình chức năng tốn kém và tiêu tốn bộ nhớ cho dữ liệu nhỏ, tại sao chúng ta cần nó cho Dữ liệu lớn?
Khác xa với các công cụ ưa thích, tôi đã cố gắng xây dựng một giải pháp cho một vấn đề cụ thể và phổ biến bằng ba cách tiếp cận: Cách bắt buộc và cách thức chức năng (đệ quy, sử dụng các bộ sưu tập). Tôi so sánh thời gian và sự phức tạp, để so sánh giữa ba cách tiếp cận.
Tôi đã sử dụng Scala để viết các hàm này vì đây là công cụ tốt nhất để viết thuật toán sử dụng ba mô hình
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))
}
Cách chức năng:
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))(_ + _)
}
Cách đệ quy:
def Fibonacci_R(n: Int): BigInt = n match {
case 1 | 2 = > 1
case _ = > Fibonacci_R(n - 1) + Fibonacci_R(n - 2)
}
Cách bắt buộc:
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
}
Tôi nhận thấy rằng lập trình chức năng là nặng! nó mất nhiều thời gian hơn và tiêu tốn nhiều dung lượng hơn trong bộ nhớ. Tôi bối rối, bất cứ khi nào tôi đọc một bài báo hoặc xem một cuộc nói chuyện, họ nói rằng chúng ta nên sử dụng lập trình chức năng trong khoa học dữ liệu. Đúng, nó dễ dàng và hiệu quả hơn, đặc biệt trong thế giới dữ liệu. nhưng nó cần nhiều thời gian hơn và nhiều không gian bộ nhớ hơn.
Vậy, tại sao chúng ta cần sử dụng lập trình Chức năng trong Dữ liệu lớn? Các thực tiễn tốt nhất để sử dụng lập trình chức năng (Scala) cho Dữ liệu lớn là gì?