Có phổ biến không sử dụng các thư viện cho các thuật toán số tiêu chuẩn, và tại sao?


54

Rất nhiều thuật toán số (tích hợp, phân biệt, nội suy, các hàm đặc biệt, v.v.) có sẵn trong các thư viện tính toán khoa học như GSL . Nhưng tôi thường thấy mã với các triển khai "cuộn tay" của các hàm này. Đối với các chương trình nhỏ không nhất thiết dành cho phân phối công khai, việc các nhà khoa học tính toán có thể tự mình thực hiện các thuật toán số (theo ý tôi là sao chép hoặc sao chép từ một trang web, Bí quyết số hoặc tương tự) khi bạn cần chúng? Nếu vậy, có một lý do cụ thể để tránh liên kết với một cái gì đó như GSL, hay nó chỉ là "truyền thống" hơn bất cứ điều gì khác?

Tôi hỏi bởi vì tôi là một fan hâm mộ lớn của việc tái sử dụng mã , điều này sẽ gợi ý rằng tôi nên cố gắng sử dụng các triển khai hiện có khi có thể. Nhưng tôi tò mò liệu có những lý do mà nguyên tắc ít có giá trị trong tính toán khoa học hơn là lập trình chung.


Quên đề cập: Tôi đặc biệt hỏi về C và C ++, trái ngược với các ngôn ngữ như Python, nơi có một lợi ích rõ ràng (tốc độ thực thi) khi sử dụng thư viện.


14
Một mặt, bạn sẽ không muốn phát minh lại bánh xe. Mặt khác, cách tốt nhất để hiểu một thuật toán (và bằng cách mở rộng, dễ dàng chẩn đoán các trường hợp thuật toán thất bại một cách ngoạn mục) là tự mình thử mã hóa một triển khai.
JM

2
Bạn có quở trách mọi định lý bạn đi qua? Có thể bạn cho nó một shot và chơi xung quanh với một số trường hợp trẻ em, nhưng trừ khi đó là trọng tâm của nghiên cứu của bạn, bạn có thể chấp nhận nó và tiếp tục với cuộc sống.
dls

3
Các nhà vật lý không phải là lập trình viên và họ không quen xử lý mã của người khác (đọc nó hoặc sửa nó). Khi họ phải sử dụng mã của người khác, mã này thường không được viết hay nhận xét tốt được viết bởi các nhà vật lý khác, một lần nữa thêm vào ý tưởng rằng viết lại nó tốt hơn là sử dụng lại nó. Điều này đúng ít nhất là trong một số lĩnh vực / cộng đồng, nhưng thái độ đang thay đổi ở những người trẻ tuổi. Mặc dù vậy, nó không tệ lắm, hãy nghĩ đến thái độ của một sinh viên CS tồi, người không thể làm gì nếu anh ta không thể tìm thấy một thư viện đủ dễ dàng cho nó.
Szabolcs

Câu trả lời:


45

Tôi đã từng tự mình thực hiện mọi thứ, nhưng gần đây đã bắt đầu sử dụng các thư viện nhiều hơn nữa. Tôi nghĩ rằng có một số lợi thế rất quan trọng của việc sử dụng thư viện, ngoài vấn đề là bạn có phải tự viết một thói quen hay không. Nếu bạn sử dụng một thư viện, bạn nhận được

  • Mã đã được kiểm tra bởi hàng trăm / nghìn / người dùng trở lên
  • Mã sẽ tiếp tục được cập nhậtcải thiện trong tương lai, mà không có bất kỳ công việc nào từ phía bạn
  • Mã được tối ưu hóa hiệu quả hơn và có thể mở rộng hơn so với những gì bạn sẽ viết trong lần thử đầu tiên
  • Tùy thuộc vào thư viện, bằng cách thiết lập giao diện cho mã trong mã của bạn, bạn có thể có quyền truy cập vào nhiều thuật toán mà bạn hiện không sử dụng nhưng có thể muốn trong tương lai

Trong gạch đầu dòng cuối cùng ở trên, tôi nghĩ về các thư viện lớn như Trilinos hoặc PETSc . Tôi có thể củng cố điều này bằng một vài ví dụ cá nhân cụ thể trong quá trình phát triển PyClaw . Mặc dù việc đơn giản hóa song song Clawpack với các cuộc gọi MPI, chúng tôi đã chọn sử dụng PETSc. Điều này cho phép chúng tôi giới hạn mã paralle trong gói dưới 300 dòng Python, nhưng thậm chí tốt hơn, bằng cách đặt dữ liệu của chúng tôi ở định dạng của PETSc, chúng tôi đã có quyền truy cập ngay vào bộ giải ẩn của PETSc, cho phép công việc hiện tại trên bộ giải ẩn trong PyClaw. Lấy ví dụ thứ hai, ban đầu PyClaw bao gồm việc tái cấu trúc WENO theo thứ tự mã thứ năm, nhưng cuối cùng chúng tôi quyết định dựa vào PyWENOgói cho việc này. Đây là một lợi ích rất lớn, vì PyWENO có thể tự động tạo các thói quen WENO theo bất kỳ trật tự nào trong một số ngôn ngữ.

Cuối cùng, nếu bạn sử dụng các thư viện, bạn có thể đóng góp lại bằng cách phát triển các cải tiến hoặc tìm lỗi, điều này sẽ có lợi cho nhiều người khác, trong khi gỡ lỗi hoặc cải thiện mã của riêng bạn chỉ có lợi cho bạn.


5
"bạn có thể đóng góp trở lại bằng cách phát triển các cải tiến hoặc tìm lỗi, điều này sẽ có lợi cho nhiều người khác." - điều đó sẽ thỏa mãn cả sự thôi thúc "mày mò / học hỏi" và sự lười biếng (không phải làm những việc đã được thực hiện). :)
JM

1
Xem thêm, trường hợp cạnh. Đối với nhiều thuật toán, việc thực hiện một cái gì đó "hoạt động" không quan trọng, nhưng sẽ không xử lý một số phần nhỏ của các trường hợp một cách chính xác. Điều này có thể ổn đối với một dự án nhỏ 1 lần, nhưng tôi không thể đếm số lần tôi bị mắc kẹt bởi các điều kiện bệnh lý trên một cái gì đó mà tôi "tối ưu hóa" bản thân.
meawoppl

34

Có rất nhiều lập trình viên liên quan đến việc liên kết đến một chức năng thư viện, đặc biệt nếu thư viện đó là mới đối với lập trình viên. Nó thường đơn giản hơn khi chỉ viết lại các thuật toán đơn giản hơn là tìm ra các chi tiết cụ thể của một thư viện cụ thể. Khi các thuật toán trở nên phức tạp hơn, hành vi này chuyển đổi.

Python đã rất xuất sắc trong việc giảm chi phí này với các công cụ như pip / easy_install và giao diện cấu trúc dữ liệu thống nhất (nghĩa là mọi thư viện dường như lấy và tạo ra một mảng numpy).


19

Một trong những dự án tôi tham gia ngay bây giờ là viết một gói mô phỏng và phân tích linh hoạt cho một lớp các máy dò vật lý hạt. Một trong những mục tiêu của dự án này là cung cấp cho các cơ sở mã được sử dụng trong những điều này trong nhiều thập kỷ tới.

Tại thời điểm này, chúng tôi đã có hai tá phụ thuộc, khiến quá trình xây dựng trở thành một cơn ác mộng đến nỗi nó đã loại bỏ một dự án riêng biệt được quản lý ra khỏi trung tâm điện toán Fermilab chỉ để cung cấp một chuỗi công cụ đáng tin cậy.

Bây giờ hãy tưởng tượng rằng bạn gặp phải nhu cầu về một số công cụ không có trong chuỗi công cụ đó (đã xảy ra với tôi vào tháng trước). Bạn có ba lựa chọn

  1. Cuộn bạn sở hữu. Với tất cả các rủi ro và rắc rối liên quan.
  2. Quét một số mã ra khỏi thư viện ở đâu đó và đưa nó vào trong Dự án. Có nghĩa là bạn phải tiếp tục bảo trì trong tương lai và bạn sẽ phải hiểu mã của người khác khi điều đó xảy ra.
  3. Đi đến những người duy trì chuỗi công cụ, cầu xin họ cho những gì bạn cần và sau đó chờ đợi một chu kỳ phát hành để có được nó. Những người này khá nhanh nhạy, nhưng bạn phải giải quyết vụ việc mà không cần mã làm việc hoặc sau khi bạn đã thực hiện (1) hoặc (2).

Thật dễ dàng để lựa chọn (1). Có lẽ quá dễ dàng.


Có, phụ thuộc được thêm vào là một nhược điểm đáng kể của việc sử dụng các thư viện.
David Ketcheson

Sự phụ thuộc cũng là nhược điểm lớn trong tâm trí tôi
Fomite

2
Có thể câu trả lời của tôi đặt quá nhiều vào thực tế của sự phụ thuộc và không đủ cho quá trình quan liêu trong việc nhận phụ thuộc được phê duyệt quảng cáo được cài đặt trong các dự án lớn.
dmckee

* của bạn ở điểm 3. (Xin lỗi vì đã bị lỗi.)
299792458

Ơ ... không. Nó nói những gì tôi muốn nói.
dmckee

12

Tôi nghĩ rằng nó khá phổ biến, với một số thuật toán nhiều khả năng được tái thực hiện hơn những người khác.

Có một sự đánh đổi khó khăn giữa việc cài đặt thư viện gây khó chịu như thế nào, việc tự thực hiện thuật toán khó đến mức nào, tối ưu hóa nó đến mức nào và thư viện phù hợp với nhu cầu của bạn như thế nào. Ngoài ra, đôi khi sử dụng thư viện chỉ là quá mức cần thiết: Tôi đã sử dụng thuật toán chia đôi chậm trong một trong các chương trình của mình vì tôi chỉ gọi nó một vài lần và tôi không muốn thêm thư viện cho việc đó.

Bạn có dễ dàng viết một phiên bản được tối ưu hóa tốt không? Nếu có, bạn có thể làm tốt hơn. Bạn sẽ nhận được chính xác những gì bạn cần và bạn sẽ không phụ thuộc vào công việc của bất cứ ai. Nhưng tất nhiên bạn thực sự cần phải biết những gì bạn đang làm: ngay cả các thuật toán đơn giản cũng có thể khó thực hiện.

Tôi sẽ tò mò muốn xem một nghiên cứu về điều này, nhưng từ quan điểm thiên vị của tôi, các nhà khoa học thường sử dụng các thư viện cho đại số tuyến tính và trình tạo số ngẫu nhiên, với hầu hết các mã còn lại là tự chế.


12
"Nhưng tất nhiên bạn thực sự cần phải biết những gì bạn đang làm: ngay cả các thuật toán đơn giản cũng có thể khó thực hiện." - Điều này không thể được nhấn mạnh đủ.
JM

10

Tôi nghĩ rằng việc thực hiện một thuật toán thay vì sử dụng thư viện đôi khi có thể giúp hiểu và kiểm soát mô hình tốt hơn. Khi tôi viết mã một số chương trình cho các tính toán khoa học, điều quan trọng đối với tôi là hiểu những gì tôi đang làm. Việc thực hiện các thuật toán quan trọng giúp tôi có được kiến ​​thức tốt hơn về vấn đề và đạt được sự kiểm soát tốt hơn về nó.

Mặt khác, đôi khi không phải là một nhiệm vụ tầm thường để chọn một thư viện cần thiết để có được một giải pháp, vì vậy tốt hơn là tìm kiếm các thuật toán đã được triển khai khi bạn chắc chắn bạn đang cố gắng đạt được điều gì và tại sao bạn muốn nó.

Nếu các thuật toán phức tạp, thì việc mã hóa chúng bằng tay mang đến cho bạn cơ hội cải thiện hiệu suất / chất lượng của giải pháp bằng cách sử dụng các tính năng dành riêng cho nhiệm vụ. Và đôi khi cần phải thay đổi thuật toán một chút, sẽ dễ dàng hơn nếu bạn biết mã mà bạn đã viết và bạn có thể chỉnh sửa nó theo cách bạn muốn.


1
+1 để cải thiện sự hiểu biết. Mặc dù đây là một vấn đề đối với các thuật toán của riêng bạn mà đối với một thói quen thư viện.
Faheem Mitha

8

Một câu trả lời là có rất nhiều biến thể nhỏ cho mã số nên rất khó để gói gọn trong thư viện. Hãy so sánh với phần mềm web, phần mềm này thường dễ cài đặt và có một bộ đầu vào và đầu ra rõ ràng. Tôi nghĩ phổ biến hơn là mọi người lấy một khung công tác hoặc thư viện lớn hoạt động như một khung (Trilinos / PETSc) và sử dụng hệ sinh thái đó để nhận được lợi ích của việc sử dụng mã cộng đồng.


7

Trước khi quyết định có sử dụng thư viện hay không, tôi nghĩ bạn cũng muốn tìm hiểu xem việc sử dụng thư viện sẽ giúp ích bao nhiêu cho mã của bạn. Nếu bạn đang sử dụng một thư viện được tối ưu hóa tốt cho hạt nhân tính toán chính, thì có lẽ nó hiệu quả hơn nhiều so với việc cố gắng tự viết.

Tuy nhiên, nếu bạn đang viết một thói quen chuyên biệt chỉ được gọi một lần trong khi thực hiện chương trình, thì việc điều chỉnh mã của bạn để phù hợp với khung theo yêu cầu của thư viện là không đáng.

(Một điều khác cần suy nghĩ: bạn sẽ cần phải tái kiến ​​trúc bao nhiêu để tận dụng thư viện? Mặc dù vậy, lý tưởng là đây là thứ bạn dự định khi thiết kế cấu trúc dữ liệu và thuật toán, để "dòng chảy" của thư viện được tính đến từ đầu.)


6

2 xu của tôi.

Tôi nghĩ nói chung là dễ dàng hơn để viết về điều này, thay vì chỉ về C / C ++. Đầu tiên, các thư viện trong các ngôn ngữ như Python không nhất thiết phải được sử dụng để có được lợi ích về tốc độ, ngay cả khi đó là hậu quả. Tôi nghĩ rằng @David bao gồm các lý do khá tốt.

Lấy nó từ đầu, việc thực hiện ngôn ngữ ở một mức độ nào đó chỉ ra những thư viện mà bạn có quyền truy cập. Các ngôn ngữ thường được sử dụng trong khoa học tính toán bao gồm C, C ++, Python, Perl, Java, Fortran và R. Các ví dụ ít phổ biến hơn có thể là Ocaml và Common Lisp. Bây giờ, vì hầu hết các ngôn ngữ này được viết bằng C, chúng có giao diện chức năng Foreign tự nhiên cho C. Tuy nhiên, không dễ để gọi, giả sử, một thư viện Perl từ Python hoặc ngược lại. Vì vậy, trong thực tế mọi người có xu hướng hoặc

  1. Sử dụng một thư viện được viết bằng ngôn ngữ thực hiện của họ, thông thường một cái gì đó là một phần của các thư viện tiêu chuẩn, hoặc có sẵn rộng rãi, hoặc

  2. Gọi thư viện C / C ++ thông qua các ngôn ngữ FFI. Điều này giả định rằng một trình bao bọc chưa tồn tại, vì nếu có, nó không dễ phân biệt với (1).

(2) thường khó hơn, vì bạn phải tự bọc chức năng C / C ++. Ngoài ra, bạn phải đóng gói thư viện hoặc thêm phụ thuộc. Vì lý do đó, mọi người có nhiều khả năng sử dụng các thư viện ngôn ngữ dựng sẵn hơn là sử dụng GSL chẳng hạn, có trong C.

Đối với các thói quen rất chung chung, giả sử tạo các mẫu ngẫu nhiên từ các bản phân phối hoặc các thói quen số cơ bản như phương trình tích phân, việc sử dụng lại một số thư viện là điều dễ dàng và phổ biến. Khi chức năng mà người ta đang cố gắng thực hiện trở nên phức tạp hơn, thì người ta sẽ không thể tìm thấy chức năng chính xác mà người ta muốn trong thư viện khác, và thậm chí người ta có thể dành nhiều thời gian để tìm kiếm và cuối cùng là điều chỉnh chức năng như cần thiết (kiểu mã / thiết kế có thể là một vấn đề chẳng hạn). Và như đã thảo luận ở trên, người ta chỉ có quyền truy cập vào một tập hợp con của các thư viện ngoài kia. Mặt khác, việc tự thực hiện một thuật toán nếu nó phức tạp và không phải là trọng tâm chính có thể gây khó khăn, và tất nhiên người ta phải đối phó với các vấn đề tốc độ đáng tiếc đó.

Vì vậy, điều này trở thành một vấn đề tối ưu hóa trong phân tích chi phí / lợi ích. Kinh nghiệm của tôi là ngay cả đối với các kỹ thuật tương đối chuẩn như MCMC, tôi vẫn thường viết mã cho riêng mình, vì nó phù hợp hơn với cách tôi thiết kế phần mềm tổng thể.

Tất nhiên, ngay cả khi bạn không sử dụng mã, bạn vẫn có thể học từ mã của người khác. Mặc dù vậy, tôi không biết các nhà khoa học thực sự bận tâm làm điều này như thế nào. Ấn tượng của tôi là đọc mã của người khác để học là một kỹ sư phần mềm.


6

Nghĩ lại về khóa học cơ học năm thứ hai của tôi, tôi nhận ra rằng một phần lý do tôi đã thực hiện các phiên bản thuật toán nổi tiếng của riêng mình là tôi được dạy để làm theo cách đó. Tôi không thể nghĩ ra một ví dụ duy nhất nơi tôi được dạy cách giao tiếp và liên kết trong một thư viện trong giáo dục vật lý đại học. Tôi có một kỷ niệm đẹp khi lần đầu tiên nhìn thấy một danh sách tọa độ của một quả bóng golf đang quay, đã tự mình tính toán giải pháp của các phương trình Newton được ghép nối trong FORTRAN. Có một sự hồi hộp và hài lòng nhất định (thậm chí là niềm tự hào) đến từ việc tính toán mọi thứ từ đầu.


1
Đây chắc chắn là một yếu tố. Và việc tập trung vào việc tự làm là cần thiết cho một phần giáo dục của một nhà khoa học tính toán. Các lập trình viên thuần túy khiến nó bị loại ra khỏi họ vào một lúc nào đó, nhưng các loại khoa học của chúng ta có thể chuyển ngay từ lớp học giới thiệu đó sang một khu dân cư dự kiến ​​gần như độc quyền bởi những người khác đi cùng tuyến đường.
dmckee

5

Tôi nghĩ người ta nên sử dụng các thư viện được thử nghiệm càng nhiều càng tốt. Hầu hết mọi người không phải là chuyên gia về điện toán số và có lẽ sẽ không thể thực hiện một giải pháp chính xác và cẩn thận như những gì có sẵn trong các thư viện được thử nghiệm tốt. Tuy nhiên, điều đó nói rằng đôi khi không có thư viện có sẵn thực hiện kết hợp các khả năng cần thiết trong một ứng dụng nhất định. Tôi đã thấy điều này xảy ra trong lĩnh vực kỹ thuật mà tôi làm việc; các mã hiện tại đã không giải quyết được tất cả các trường hợp và cuối cùng ai đó đã thực hiện một bộ giải từ đầu.


1
Nếu thư viện không đáp ứng tất cả các nhu cầu của bạn, tôi khuyên bạn nên mở rộng mã thư viện và gửi một bản vá. Bằng cách đó, bạn sẽ có lợi cho nhiều người khác với công việc của bạn và những người khác cũng sẽ kiểm tra mã của bạn cho bạn. Tất nhiên, điều này giả định rằng mã thư viện được viết theo cách đủ linh hoạt để có thể mở rộng để đáp ứng nhu cầu của bạn.
David Ketcheson

Tôi đồng ý, đó là một giải pháp tuyệt vời và mọi người nên làm gì nếu có thể.
mhucka

5

Vấn đề cơ bản thường là với giao diện giữa ứng dụng và thư viện. Một lập trình viên ứng dụng có kiến ​​thức về vấn đề thường bị mất khi chuyển vấn đề (ví dụ như ma trận) đến thư viện. Kiến thức này là như vậy mà khai thác nó nhiều hơn là bù đắp lợi ích của việc sử dụng thư viện được tối ưu hóa cao. Kết quả là, lập trình viên ứng dụng "cuộn" việc thực hiện của chính mình để khai thác kiến ​​thức.

Do đó, một thư viện thực sự tốt cần có kiến ​​thức như vậy để được truyền từ ứng dụng vào thư viện, để thư viện cũng có thể tận dụng lợi thế của nó.


3

Ngoài tất cả những điều đã nói ở trên, tôi sẽ lặp lại câu trả lời của mình từ câu hỏi "Fortran vs C ++": Tài sản quý giá nhất mà một lập trình viên có là thời gian của cô ấy. Có, phụ thuộc bên ngoài thường khó xử. Nhưng dành thời gian để thực hiện lại, gỡ lỗi và kiểm tra các thuật toán mà những người khác đã thực hiện hầu như luôn luôn là ngu ngốc, và kết quả cũng sẽ hiếm khi tốt như mã được viết bởi các chuyên gia về một chủ đề cụ thể. Sử dụng lại những gì người khác đã làm!


Tôi đưa ra câu trả lời của riêng tôi về chủ đề này. Bạn có thể học được nhiều hơn nữa khi bạn viết lại tất cả các chi tiết. Bây giờ tôi làm việc được 5-6 năm với những đám mây điểm. Ba năm đầu tiên tôi đã tự viết tất cả các dấu chấm câu. Nửa sau tôi đã sử dụng Thư viện đám mây điểm. Tôi không thể chứng minh, nhưng tôi coi mình là chuyên gia mạnh hơn về PCL bằng cách dành ba năm đầu tiên để suy nghĩ về các giải pháp mà những người khác đã cung cấp.
Jan Hackenberg

@JanHackenberg - vâng, nhưng hãy để tôi nói thẳng: bạn vừa lãng phí ba năm cuộc đời để phát minh lại bánh xe. Hãy tưởng tượng bạn có thể làm được bao nhiêu thứ mới nếu bạn đã sử dụng những gì người khác đã làm!?
Wolfgang Bangerth

Tôi quyết định viết bằng Java trong năm đầu tiên bởi vì tại thời điểm này, tôi coi kỹ năng lập trình của mình (không phải lý thuyết về tin học) gần bằng không. Java vẫn là ngôn ngữ tôi giỏi nhất trong thực tế. Tôi cũng coi Java là lựa chọn tốt vì hỗ trợ đa nền tảng dễ dàng. Tôi bước vào một chiếc ghế không có hỗ trợ thông tin trong phd (lâm nghiệp truyền thống). Tôi đã nhảy lên c ++ khi tôi nhận ra sai lầm của mình và tôi có thể (sau khi xuất bản, không phải trước đó).
Jan Hackenberg

BTW Tôi không đồng ý trong 3 năm của cuộc đời. Điều này có nghĩa là tôi chỉ có hai năm hữu ích trong trải nghiệm hậu phd. Hôm nay tôi có thể lắp 10 tỷ hình trụ trong đám mây điểm lâm nghiệp và để máy quyết định cái nào tốt để đại diện cho cây. ~ 50 người dùng của tôi cũng có thể làm như vậy. Trong ~ 1 giờ. Tất cả các mẹo tôi học được bằng cách học một cách khó khăn và tốn thời gian. Tôi quyết định không bao giờ học cách sử dụng vi, nhưng khi mọi người vượt qua yêu cầu học tập cần thiết để sử dụng cách hiệu quả nhất để tạo mã tôi tin họ.
Jan Hackenberg

2

Nhóm tôi làm việc với việc sử dụng các thư viện càng nhiều càng tốt. Tôi là một trong số ít lập trình viên và những người còn lại chọn lập trình trong công việc. Họ biết đủ những hạn chế của bản thân để biết nơi nào họ không nên lao vào. IMSL là thư viện ưa thích. Những thứ như GSL sẽ bị cấm do hạn chế cấp phép, mặc dù đây là một cơ quan liên bang và dù sao chúng tôi cũng cung cấp phần mềm của chúng tôi.


2

"Tái sử dụng chủ yếu là một hiện tượng xã hội. Tôi có thể sử dụng phần mềm của người khác với điều kiện

  1. nó hoạt động
  2. nó là dễ hiểu
  3. nó có thể cùng tồn tại
  4. nó được hỗ trợ (hoặc tôi sẵn sàng hỗ trợ nó, chủ yếu là tôi không)
  5. nó là kinh tế
  6. Tôi có thể tìm nó.

"- B. Stroustrup, Ngôn ngữ lập trình C ++ 2 ed. (1991) trang 383.


1

Một số lý do tốt đã được đưa ra bởi những người khác để sử dụng các thư viện, và cũng để cuộn các thói quen của riêng bạn.

Đôi khi bạn có thể tăng tốc tính toán cho một ứng dụng cụ thể vì bạn biết trước rằng bạn sẽ không bao giờ cần phạm vi rộng của các giá trị mà thói quen thư viện bao trùm, hoặc độ chính xác mà các thói quen đó cung cấp.

Tất nhiên, rất nhiều phụ thuộc vào ứng dụng cụ thể và bao nhiêu lần thói quen thư viện sẽ được gọi. Tại sao bạn gọi một thói quen thư viện cho các hàm Bessel hàng tỷ lần nếu bạn chỉ cần một vài số liệu quan trọng cho một phạm vi nhỏ x, và một số kỹ thuật đơn giản hơn sẽ đủ cho nhu cầu của bạn?


0

Rất ít để thêm, chúng ta phải sử dụng lại mã, đó là về sự bền vững của mã và đóng góp cho xã hội, nhưng đó là tất cả ở trên.

Lý do tại sao chúng tôi không sử dụng lại mã là vì nếu bạn bắt đầu lập trình viên thì khó hiểu mã người khác. Điều này đặc biệt khó khăn với C ++ nâng cao và bạn cũng có thể thực hiện một số thủ thuật trong C thuần túy.

Lúc đầu, người ta thường hiểu phương pháp, nhưng không phải là nó được triển khai trong thư viện, hoặc đơn giản là làm thế nào để sử dụng thư viện với giao diện chung, kiểm soát lỗi và quy ước, rất thường được ghi lại cho các lập trình viên có kinh nghiệm. Điều này mang lại ảo tưởng là tốt hơn để thực hiện một phương pháp tiêu chuẩn, như chính yếu tố LU. Hơn nữa, các lập trình viên mới đánh giá thấp giá trị của kiểm tra mã, xác nhận hợp lệ và tính di động cho các hệ điều hành khác nhau. Vì vậy, lý do cuối cùng là sự lười biếng, viết mã riêng trông giống như một giải pháp nhanh hơn và dễ dàng hơn.

Thực tế là chúng ta có thể tìm hiểu nhiều hơn bằng cách sử dụng và đọc mã hơn là tự lập trình từ đầu.

Sự lười biếng thúc đẩy tôi trong hầu hết thời gian, tôi cũng nghĩ rằng phần lớn mọi người. Vì lý do tương tự, một số viết mã từ đầu và khác sử dụng các thư viện hiện có.


-1

Các thuật toán thư viện cung cấp trái ngược với các triển khai riêng:

  • Họ là chung chung và templated. Sau này bạn có thể xác định lại việc thực hiện của mình mà không phải lo lắng thay đổi mã của riêng bạn, điều được cho là có nhiều ràng buộc.
  • Có sự an toàn so với các trường hợp thoái hóa của dữ liệu đầu vào. Rất nhiều thuật toán hình học tính toán, ví dụ như các thân tàu lồi, cần xử lý ví dụ như colinearity của ba điểm. Bạn có thể bỏ qua những trường hợp đó nếu bạn không bao giờ có kế hoạch phân phối mã của mình và cũng không muốn sử dụng lại mã của mình trong tương lai.
  • Chúng cung cấp độ phức tạp thời gian chạy tối thiểu cho các cấu hình đầu vào trường hợp dự kiến ​​hoặc xấu nhất. Các thuật toán cấp cao hơn có các khối xây dựng thường là các thuật toán cấp thấp hơn, ví dụ như các thuật toán sắp xếp hoặc các loại dữ liệu đặc biệt. Sắp xếp nhanh có thể là lựa chọn phổ biến nhất để sắp xếp dữ liệu, nhưng nếu việc triển khai thuật toán của bạn phải đảm bảo n (log (n)) thì bạn không thể sử dụng nó.
  • Chúng là bộ nhớ sử dụng hiệu quả
  • Họ đang tiếp tục tối ưu hóa thời gian chạy
  • Nếu được hỗ trợ, nói chung là đóng "lỗi" miễn phí, đặc biệt nếu bạn làm việc với chi nhánh chính. Không có gì được thử nghiệm nhiều hơn một thư viện phân phối tốt. Không phải mọi lỗi gặp sự cố, không phải mọi lỗi đều tạo ra kết quả không hợp lý. Việc triển khai thuật toán của bạn vẫn có thể tạo ra kết quả chấp nhận được, nhưng không tốt như được thiết kế cho. Lỗi càng ít nhìn thấy thì bạn càng ít có khả năng phát hiện ra nó.

Tôi vẫn cho rằng nó tốt khi tham gia vào một lĩnh vực mới để tự mình thực hiện một phiên bản thuật toán dễ hiểu. Tôi mất rất nhiều thời gian trong tổng số. Tôi đã mua và đọc sách, có tên là Press et al. Tôi luôn đọc nhiều lý thuyết trước và trong khi thực hiện. Và sau khi hiểu các khái niệm chung về một lĩnh vực và trải nghiệm các bẫy trong thực tế đối với tôi, đã đến lúc chuyển sang các khía cạnh triển khai thư viện tốt hơn về mọi mặt. Tôi nghĩ bạn sẽ trở thành người sử dụng thư viện tốt hơn nếu bạn tự mình viết một thuật toán "hello world" trong trường thư viện.

Nếu bạn làm việc trong một nhóm lớn hơn, đó có thể không phải là sự lựa chọn của riêng bạn, nhóm của bạn có sử dụng một thư viện cụ thể hay không. Nhóm nòng cốt có thể làm quyết định. Và có thể có một người chịu trách nhiệm cho thư viện ràng buộc trong dự án của bạn với quy hoạch thời gian riêng của nó. Viết lại một thuật toán bạn có thể làm với kế hoạch thời gian của riêng bạn, không dựa vào quyết định của người khác.

Nếu bạn đang ở một mình và muốn phân phối thì có một vấn đề khác. Tôi coi cũng như nhiều mã nguồn khác là tài nguyên hữu ích nhất. Nhiều người cho tất cả các nhà thông tin có thể đồng ý ở đây. Trong một lĩnh vực ứng dụng ngoài tin học, có thể cần phải cung cấp một ngoại lệ được biên dịch sẵn trên các cửa sổ. Trong Linux, bạn có thể tự mình thiết lập mọi thứ tương đối dễ dàng trong trường hợp các thư viện sử dụng nguồn mở.

Viết lại một thuật toán theo cách riêng của bạn mang lại sự tự do. Dự án của bạn có thể không hỗ trợ GPL lisence của GSL chẳng hạn.

Sự thiếu sót có thể là ràng buộc duy nhất độc lập với quan điểm của người nghiên cứu.


1
Thật vô lý khi nghĩ rằng "tự mình thực hiện một thuật toán" và "học [ing] cú pháp thư viện" sẽ "tốn cùng một lúc". Điều đó thậm chí không đúng với các chức năng đơn giản như "strcat". Điều chắc chắn nhất không phải là trường hợp đối với bất cứ điều gì trong LAPACK, ví dụ, hoặc trên các thư viện cấp cao hơn.
Wolfgang Bangerth

@WolfgangBangerth Cảm ơn bạn đã phản hồi. Tôi đọc lại những gì tôi đã viết và tôi không muốn chuyển thông điệp rằng các triển khai riêng có thể được tính lại. Nhưng tôi đã học được rất nhiều. "Cả hai có thể có giá hai tuần" của tôi không phải là một ví dụ tốt. Như một vấn đề thực tế, tôi đã phải trả giá cho lần cuối cùng "học cú pháp" 2 tuần khi tôi chuyển mẫu Java sang C ++ và tôi cũng đã học cú pháp C ++ cơ bản tại thời điểm này. Tôi đã vật lộn nhiều hơn với Con trỏ sau đó với thư viện mới của mình. Hai tuần đối với bất kỳ thuật toán được triển khai nào của tôi có thể là thời gian mã hóa vốn là khoản đầu tư nhỏ của tôi (đọc sách trước đó mất nhiều thời gian hơn).
Jan Hackenberg

Đầu tư không phải là bằng văn bản một thuật toán nhỏ. Đó là nhanh chóng, và thực sự đôi khi có thể mất nhiều thời gian như học một thư viện khác. Những gì tốn rất nhiều thời gian là để gỡ lỗi mọi thứ, và để có được tất cả các trường hợp góc đúng. Nếu bạn sử dụng một thư viện phát triển tốt, bạn sẽ biết rằng nếu sản phẩm vector ma trận hoạt động cho ma trận vuông, thì nó cũng sẽ hoạt động cho ma trận hình chữ nhật. Đối với phần mềm của riêng bạn, bạn có thể thực hiện và gỡ lỗi phần mềm này, mặc dù bạn nghĩ rằng bạn đã hoàn thành chức năng. Bạn sẽ trở lại cùng một chức năng nhiều lần. Đó là những gì tốn thời gian.
Wolfgang Bangerth

@WolfgangBangerth Tôi đồng ý với tất cả các lý lẽ của bạn. Điểm duy nhất của tôi là bạn học được nhiều lý thuyết hơn khi bạn cần tự mình xử lý các trường hợp Góc đó. Phiên bản đầu tiên của tôi về câu trả lời của tôi thực sự nghe có vẻ như không có gì khác biệt. Tôi mệt mỏi khủng khiếp. Tôi viết trong câu trả lời được cải thiện rất nhiều về lợi ích ổn định của các thư viện. Đối với tôi đó là sự đánh đổi giữa thời gian sử dụng và Kiến thức kiếm được.
Jan Hackenberg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.