2010-07-25 40 views
7

Tôi mới sử dụng Scala và chỉ đọc Scala By Example. Trong chương 2, tác giả có 2 phiên bản Quicksort khác nhau.Hiệu suất Scala: bắt buộc so với kiểu chức năng

Một là bắt buộc phong cách:

def sort(xs: Array[Int]) { 
    def swap(i: Int, j: Int) { 
     val t = xs(i); xs(i) = xs(j); xs(j) = t 
    } 
    def sort1(l: Int, r: Int) { 
     val pivot = xs((l + r)/2) 
     var i = l; var j = r 
     while (i <= j) { 
      while (xs(i) < pivot) i += 1 
      while (xs(j) > pivot) j -= 1 
      if (i <= j) { 
       swap(i, j) 
       i += 1 
       j -= 1 
      } 
     } 
     if (l < j) sort1(l, j) 
     if (j < r) sort1(i, r) 
    } 
    sort1(0, xs.length - 1) 
} 

Một là chức năng phong cách:

def sort(xs: Array[Int]): Array[Int] = { 
    if (xs.length <= 1) xs 
    else { 
    val pivot = xs(xs.length/2) 
    Array.concat(
     sort(xs filter (pivot >)), 
      xs filter (pivot ==), 
     sort(xs filter (pivot <))) 
    } 
} 

Lợi thế rõ ràng là phong cách chức năng có hơn phong cách bắt buộc là conciseness. Nhưng những gì về hiệu suất? Kể từ khi nó sử dụng đệ quy, chúng ta phải trả tiền cho các hình phạt hiệu suất giống như chúng tôi làm trong các ngôn ngữ mệnh lệnh khác như C? Hoặc, Scala là một ngôn ngữ lai, "cách Scala" (chức năng) được ưa thích, do đó hiệu quả hơn.

Lưu ý: Tác giả đã đề cập đến kiểu chức năng sử dụng nhiều bộ nhớ hơn.

+2

có thể trùng lặp của [Lập trình chức năng scala có chậm hơn mã hóa truyền thống không?] (Http://stackoverflow.com/questions/2794823/is-scala-functional-programming-slower-than-traditional-coding) – missingfaktor

+2

"Ngắn gọn" không giống như "có thể đọc được". Bằng chứng: [ngôn ngữ lập trình J] (http://en.wikipedia.org/wiki/J_ (programming_language)) –

+1

Tôi nghĩ bây giờ tôi đã hiểu rằng tác giả của Scala By Example đang cố gắng thể hiện một cách khác để giải quyết vấn đề ngắn gọn hơn rất nhiều. Tóm lại: bạn lập trình ngắn gọn nhất có thể trong tất cả các phần của mã của bạn, để bạn có được sự đồng nhất tối đa, năng suất. Sau đó chạy ứng dụng của bạn và nếu quá chậm, hãy lập hồ sơ và tối ưu hóa các phần nút cổ chai. – sivabudh

Trả lời

11

Điều đó tùy thuộc. Nếu bạn nhìn vào các nguồn Scala, thường có một phong cách bắt buộc được sử dụng "dưới mui xe" để có thể thực hiện - nhưng trong nhiều trường hợp chính xác những điều chỉnh này cho phép bạn viết performant chức năng mã. Vì vậy, thông thường bạn có thể đưa ra một giải pháp chức năng đủ nhanh, nhưng bạn phải cẩn thận và biết những gì bạn làm (đặc biệt là liên quan đến cấu trúc dữ liệu của bạn). Ví dụ. mảng concat trong ví dụ thứ hai không đẹp, nhưng có lẽ không quá tệ - nhưng việc sử dụng Lists ở đây và concat chúng với ::: sẽ là quá mức cần thiết.

Nhưng đó không phải là nhiều hơn đoán được giáo dục nếu bạn không thực sự đo hiệu suất. Trong các dự án phức tạp, thật khó để dự đoán hiệu suất, đặc biệt là những thứ như tạo đối tượng và các cuộc gọi phương thức ngày càng được tối ưu hóa bởi trình biên dịch và JVM.

Tôi khuyên bạn nên bắt đầu với phong cách chức năng. Nếu nó quá chậm, hãy cấu hình nó. Thông thường có một giải pháp chức năng tốt hơn. Nếu không, bạn có thể sử dụng phong cách bắt buộc (hoặc kết hợp cả hai) như một phương sách cuối cùng.

+0

Nhưng nó đánh bại mục đích đúng không? Ý tôi là, Scala được ca ngợi là ngôn ngữ đầu tiên có chức năng lập trình hàm và đối tượng. Nhưng, nếu bạn không thể chắc chắn rằng lập trình theo cách chức năng sẽ hiệu quả, thì những người quan tâm đến hiệu suất sẽ kết thúc làm Scala theo cách "Java"? – sivabudh

+5

Nhìn vào các ví dụ. Cái nào dễ hiểu hơn? Phong cách chức năng thực sự cho bạn biết thuật toán làm gì: "chọn yếu tố trục, sắp xếp các phần tử nhỏ hơn, sắp xếp các phần tử lớn hơn và đặt mọi thứ lại với nhau". Đây là một lợi thế rất lớn so với ví dụ bắt buộc, mà chủ yếu quan tâm đến các biến vòng lặp và các chỉ mục mảng. Vì vậy, nếu phong cách chức năng hoạt động tốt, chúng tôi thường là vàng, nhưng chúng tôi vẫn có phong cách bắt buộc như là giải pháp quay trở lại. Tuy nhiên không thiết lập mệnh đề hướng đối tượng ==. Các lớp và đối tượng có thể hoạt động tốt trong ngữ cảnh chức năng. – Landei

+9

Trong bất kỳ dự án lớn nào, bạn sẽ thấy rằng rất ít mã thực sự phải có hiệu quả đáng kinh ngạc. Trong những trường hợp đó, đúng là bạn sẽ thường phải quay trở lại các cấu trúc bắt buộc. Scala hỗ trợ điều đó.Phần còn lại của thời gian, bạn tốt hơn off mã hóa theo cách mà thiết kế của bạn là hiển nhiên rõ ràng trong mã của bạn càng tốt. Đó có thể là chức năng, thủ tục, hướng đối tượng hoặc kết hợp chúng. Scala hỗ trợ tất cả những thứ đó. –

Các vấn đề liên quan